annotate paper/chapter3.tex @ 10:a349b2c01cfe

add graffle
author Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
date Tue, 28 Jan 2014 06:40:52 +0900
parents 37efb7dc0bda
children ff03e6179f19
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
1 \chapter{Haskellによる並列データベースの実装}\label{ch:impl}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
2
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
3 本章では、並列データベースの実装について述べる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
4 まず、実装した木構造データベースの利用方法について述べ、次に詳細な設計と実装について述べる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
5
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
6 \section{木構造データベース Jungle}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
7 木構造データベース Jungle は、Haskell で実装された並列データベースである。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
8 非破壊的木構造の方法に則ったAPIを提供する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
9 本研究では、HTTP サーバ Warp と組み合わせて掲示板システムとして利用しているが、他のシステムに組み込むことも可能である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
11 \subsubsection{木の作成}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
12 Jungle は複数の木構造を保持する事ができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
13 木構造は、名前を付けて管理する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
14 名前を利用することで他の木構造と識別し、作成・編集を行う。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
15
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
16 createJungle で、データベースを作成できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
17 木を作成するには、createTree を利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
18 createTree には、createJungle で作成したデータベースと新しい木の名前を渡す。\\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
19
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
20 \begin{lstlisting}[caption=データベースと木の作成]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
21 jungle <- createJungle
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
22 createTree jungle "name of new tree here"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
23 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
24
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
25 \subsubsection{ルートノード}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
26 Jungle は参照および編集に木構造のルートノードを活用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
27 ルートノードに関する API を説明する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
28
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
29 getRootNode は、最新のルートノードを取得できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
30 データベースと木の名前を渡すことで利用する。\\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
31
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
32 \begin{lstlisting}[caption=最新のルートノードの取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
33 node <- getRootNode jungle "your tree name here"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
34 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
35
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
36
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
37 木構造を編集する API は全て Node を受け取って Node を返す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
38 その返ってきた Node をルートノードとして新たに登録することで木構造が更新される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
39 updateRootNode は、データベースと木の名前、変更して返ってきた木構造を渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
40 updateRootNodeをした後は、getRootNodeで取得できるルートノードが更新された状態になっている。\\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
41
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
42 \begin{lstlisting}[caption=ルートノードの更新]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
43 updateRootNode jungle "your tree name here" node
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
44 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
45
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
46 updateRootNodeWithは、ノードを更新する関数とデータベース、木の名前を渡して利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
47 ノードを更新する関数とは、ノードを受け取ってノードを返す関数である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
48 このupdateRootNodeWithを利用することで、getRootNodeをした後、編集しupdateRootNodeを行う一連の操作がatomicallyに行われることが保証される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
49 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
50
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
51 \begin{lstlisting}[caption=関数を渡してルートノードの更新]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
52 updateRootNodeWith func jungle "your tree name here"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
53 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
54
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
55 \subsubsection{木の編集}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
56 木の編集には、Node を使う。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
57 木の編集に用いる API は全て Node を受け取って Node を返す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
58 非破壊的木構造を利用しているため、getRootNode などで取得してきた Node は他のスレッドと干渉することなく自由に参照、編集できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
59 これらの編集のためのAPIは、編集後updateRootNodeするか、ひとつの関数にまとめてupdateRootNodeWithをすることで木構造に反映させることができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
60
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
61 編集対象のノードを指定するには、NodePath を利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
62 NodePath は、ルートノードからスタートし、ノードの子どもの場所を次々に指定したものである。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
63 Haskell の基本データ構造であるリストを利用している。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
64
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
65
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
66 \begin{figure}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
67 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
68 \includegraphics[width=100mm]{./images/nodepath.pdf}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
69 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
70 \caption{NodePath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
71 \label{fig:nodepath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
72 \end{figure}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
73
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
74 addNewChildAt で、ノードに新しい子を追加できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
75 addNewChildAt には、Node と NodePath を渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
76 子には Position という場所の情報があるが、インクリメントしながら自動的に指定される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
77 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
78 \begin{lstlisting}[caption=子の追加]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
79 new_node = addNewChildAt node [l,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
80 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
81
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
82 deleteChildAt で、ノードの子を削除できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
83 deleteChildAt には、Node と NodePath、削除したい子のPositionを指定する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
84 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
85 \begin{lstlisting}[caption=子の削除]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
86 new_node = deleteChildAt node [1,2] 0
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
87 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
88
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
89 putAttribute で、ノードに属性を追加できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
90 putAttribute には、Node と NodePath、Key、Valueを渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
91 Key は String、 Value は、ByteString である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
92 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
93 \begin{lstlisting}[caption=属性の追加]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
94 new_node = putAttribute node [1,2] "key" "value"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
95 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
96
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
97 deleteAttribute で、ノードの属性を削除できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
98 deleteAttribute には、Node と NodePath、Keyを渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
99 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
100 \begin{lstlisting}[caption=属性の削除]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
101 new_node = deleteAttribute node [1,2] "key"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
102 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
103
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
104
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
105 \subsubsection{木の参照}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
106 木の参照にも Node を用いる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
107 様々な参照の API があるため、ひとつずつ紹介していく。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
108
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
109 getAttributes は、対象の Path に存在する属性を Key を用いて参照できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
110 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
111 \begin{lstlisting}[caption=属性の取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
112 bytestring = getAttributes node [1,2] "key"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
113 \end{lstlisting}
2
d8b94e828d79 add tex files
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
115 あるNodeに存在する全ての子に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
116 getChildren は、対象の Node が持つ全ての子を Node のリストとして返す
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
117 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
118 \begin{lstlisting}[caption=対象のNodeの全ての子を取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
119 nodelist = getChildren node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
120 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
121
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
122 あるNodeに存在する全ての子に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
123 getChildren と違い、子のPositionも取得できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
124 assocsChildren は、対象の Node が持つ全ての子を Position とのタプルにし、そのタプルのリストを返す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
125 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
126 \begin{lstlisting}[caption=対象のNodeの全ての子とPositionを取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
127 nodelist = assocsChildren node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
128 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
129
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
130
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
131 あるNodeに存在する全ての属性に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
132 assocsAttribute は、対象の Node が持つ全ての属性を、Key と Value のタプルとし、そのタプルのリストを返す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
133 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
134 \begin{lstlisting}[caption=対象のNodeの全てのAttributeのKeyとValueを取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
135 attrlist = assocsAttribute node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
136 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
137
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
138 numOfChild では、対象の Node が持つ子どもの数を取得できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
139 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
140 \begin{lstlisting}[caption=対象のNodeの子どもの数を取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
141 num = numOfChild node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
142 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
143
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
144 currentChild では、対象の Node が持つ最新の子を取得できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
145 \\
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
146 \begin{lstlisting}[caption=対象のNodeの最新の子を取得]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
147 node = currentChild node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
148 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
149
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
150 \section{木構造データベース Jungle の実装}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
151 \subsubsection{開発環境}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
152 実装には、Haskell を用いる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
153 \subsubsection{全体の構造}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
154 木構造の集まりを表現する Jungle、単体の木構造を表現する Node から構成される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
155 Jungle は複数の Node の集まりである。Jungle を利用して最新のルートノードを取得することができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
156 Node は子と属性を任意の数持てる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
157
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
158 \begin{table}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
159 \caption{全体の構造}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
160 \label{tab:components}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
161 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
162 \begin{tabular}{|c||c|} \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
163 名前 & 概要 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
164 Jungle & 木の作成・取得を担当する。 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
165 Node & 基本的なデータ構造、子と属性を任意の数持てる。 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
166 RootNode & 木構造のルートを表す。Jungle から最新のルートノードを取得できる。 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
167 children & 子となるノードを任意の数持つことができる。 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
168 attributes & Key と Value の組み合わせを任意の数持つことができる。 \\ \hline
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
169 \end{tabular}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
170 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
171 \end{table}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
172
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
173 \subsection{Jungle}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
174 Jungle は木構造の集まりを表現する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
175 木には名前がついており、ルートノードの情報も一緒に保持している。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
176
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
177 \subsubsection{木の取り扱い}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
178 Jungle の木の取り扱いには、Haskell の Data.Map を利用している。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
179 Haskell で連想配列を扱いたい場合、平衡木によって実装された Data.Map を一般的に用いる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
180 Haskell のライブラリには配列や、ハッシュ・テーブルといったものも存在するがあまり使われない。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
181 配列は参照に適しているが、データを追加する際に配列を再作成するためコストが大きい。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
182 ハッシュ・テーブルは更新操作に副作用を伴うため、IOモナドの中でしか使うことが出来ず、扱いにくい。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
183 Data.Mapは、挿入や参照が O(log n) で済む。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
184
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
185 また、木の取り扱いには Haskell のソフトウェア・トランザクショナル・メモリ (STM) を利用して状態を持たせ、スレッド間で共有できるようにしてある。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
186 これは、木構造の各スレッドから作成できるようにするためである。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
187 STM は、スレッド間でデータを共有するためのツールである。STM を利用することでロック忘れによる競合状態や、デッドロックといった問題から解放される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
188 STM は、アクションのブロックを atomically コンビネータを使ってトランザクションとして実行する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
189 いったんブロック内に入るとそこから出るまでは、そのブロック内の変更は他のスレッドから見ることはできない。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
190 こちら側のスレッドからも他のスレッドによる変更はみることはできず、実行は完全に孤立して行われる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
191 トランザクションから出る時に、以下のことが1つだけ起こる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
192 \begin{itemize}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
193 \item 同じデータを平行して変更したスレッドが他になければ、加えた変更が他のスレッドから見えるようになる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
194 \item そうでなければ、変更を実際に実行せずに破棄し、アクションのブロックを再度実行する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
195 \end{itemize}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
196 STM は簡単に使え、また同時に安全である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
197
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
198 \subsection{Node}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
199 Node は木構造を表現するデータ構造である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
200 再帰的に定義されている。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
201 各ノードは Children としてノードを複数持つことができる(図\ref{fig:node_components})。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
202
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
203 \begin{figure}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
204 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
205 \includegraphics[width=110mm]{./images/node_component.pdf}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
206 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
207 \caption{Nodeの構成要素}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
208 \label{fig:node_components}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
209 \end{figure}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
210
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
211 Children および Attributes も Data.Map を用いて定義されている(ソースコード \ref{src:node})。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
212
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
213 \begin{lstlisting}[label=src:node, caption=Nodeのデータ型の定義]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
214 data Node = Node
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
215 { children :: (Map Int Node)
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
216 , attributes :: (Map String ByteString) }
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
217 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
218
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
219 \subsubsection{ルートノード}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
220 非破壊的木構造ではノードは破壊されない。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
221 そのため、どのノードが最新のルートノードなのかという情報が必要である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
222 この情報もスレッドセーフに取り扱う必要があるため、Haskell の ソフトウェア・トランザクショナル・メモリ (STM) を用いて管理している。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
223
5
658281be77ec describe the abstract
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
224 \section{並列実行}
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
225 木構造データベース Jungle は、並列に実行することができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
226 アプリケーション側で、データベースを参照や変更する際に各スレッドから呼び出しても問題ない。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
227 利用方法も、シングルスレッドで実行する場合と同じである。
2
d8b94e828d79 add tex files
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
229 \section{Haskell の生産性}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
230 Java を用いた Jungle の実装と比較して、コード行数が約 3000 行から約 300 行へと短くなった。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
231
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
232 これは Haskell の表現力が高いためである。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
233 Haskell では、データ型を簡単に作成することができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
234 再帰的なデータ構造の定義も容易である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
235 共通の性質を扱うための型クラスという仕組みが存在し、既存のライブラリを作成したデータ型に利用できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
236 また、Haskellは参照透過性を持つため、コードの再利用が行い易く、関数同士の結合も簡単である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
237
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
238 同じような機能を実装する場合でも、Java と比較してコード行数が短くなり生産性が向上する。