annotate paper/chapter3.tex @ 34:345eacdf29e4

add apendix
author Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
date Mon, 03 Feb 2014 16:54:48 +0900
parents 21f075c483cc
children ec3488a9ddd4
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
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
3 本章では、並列データベース Jungle の実装について述べる。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
4 まず、実装した非破壊的木構造データベースの利用方法について述べ、次に詳細な設計と実装について述べる。
10
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}
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
7 非破壊的木構造データベース Jungle は、Haskell で実装された並列データベースである。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
8 非破壊的木構造の方法に則ったAPIを提供する。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
9
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
10 % 本研究では、HTTP サーバ Warp と組み合わせて掲示板システムとして利用しているが、他のシステムに組み込むことも可能である。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
11 Jungle の基本的な使い方の手順について説明する。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
12 \begin{enumerate}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
13 \item{木構造を保持する Jungle を作成する(Jungle は複数の木を保持できる)}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
14 \item{Jungle 内に新しい木を名前をつけて作成する}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
15 \item{木の名前を用いて、ルートノードの取得を行い、データを参照する}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
16 \item{もしくは、木の名前を用いて、ルートノードの更新を行う}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
17 \end{enumerate}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
18
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
19 \subsubsection{Jungle 内部のデータ型}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
20 Jungle の内部のデータ型を表\ref{tab:components}に表す。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
21 木構造の集まりを表現する Jungle、単体の木構造を表現する Tree がある。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
22 Tree は外部から見えないように実装されている。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
23
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
24 Jungle は複数の Tree の集まりである。Jungle と木構造の名前を利用して最新のルートノードを取得することができる。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
25 Node は子と属性を任意の数持てる。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
26
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
27 \begin{table}[!htbp]
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
28 \caption{内部のデータ型}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
29 \label{tab:components}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
30 \begin{center}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
31 \begin{tabular}{|c||c|} \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
32 型名 & 概要 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
33 Jungle & 木の作成・取得を担当する。 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
34 Tree & 木の名前とルートノードの情報を保持している。 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
35 Node & 基本的なデータ構造、子と属性を任意の数持てる。 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
36 children & 子となるノードを任意の数持つことができる。 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
37 attributes & Key と Value の組み合わせを任意の数持つことができる。 \\ \hline
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
38 \end{tabular}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
39 \end{center}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
40 \end{table}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
41
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
42 \newpage
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
43
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
44 \subsubsection{Jungle と木の作成}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
45 Jungle は複数の非破壊的木構造を扱うことができる(図\ref{fig:jungle})。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
46
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
47 \begin{figure}[!htbp]
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
48 \begin{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
49 \includegraphics[scale=0.7]{./images/jungle.pdf}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
50 \end{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
51 \caption{複数の木を扱えるJungle}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
52 \label{fig:jungle}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
53 \end{figure}
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
54
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
55 木構造の識別には、名前を利用する。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
56 名前を付けて作成し、名前を用いることで参照を行う。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
57
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
58 createJungle で、Jungle を作成できる。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
59
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
60 木を作成するには、createTree を利用する。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
61 createTree には、createJungle で作成した Jungle と新しい木の名前を渡す。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
62
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
63 型の定義と実際のコードを示す。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
64
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
65 \begin{lstlisting}[caption=データベースと木の作成]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
66 createJungle :: IO Jungle
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
67 createTree :: Jungle -> String -> IO ()
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
68
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
69 jungle <- createJungle
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
70 createTree jungle "name of new tree here"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
71 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
72
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
73 \subsubsection{ルートノード}
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
74 非破壊的木構造データベース Jungle では、木の最新の状態を更新・参照するのにルートノードを使う。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
75 ルートノードは、最新の木構造の根がどれかの情報を保持している(図\ref{fig:getrootnode})。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
76
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
77 \begin{figure}[!htbp]
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
78 \begin{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
79 \includegraphics[scale=0.7]{./images/get_root_node.pdf}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
80 \end{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
81 \caption{ルートノード}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
82 \label{fig:getrootnode}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
83 \end{figure}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
84
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
85 ルートノードに関する API を説明する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
86
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
87 getRootNode は、最新のルートノードを取得できる。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
88 データベースと木の名前を渡すことで利用できる。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
89 例えば、図\ref{fig:getrootnode}の状態の時は、B というルートノードが取得できる。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
90
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
91 \begin{lstlisting}[caption=最新のルートノードの取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
92 getRootNode :: Jungle -> String -> IO Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
93
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
94 node <- getRootNode jungle "your tree name here"
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
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
98 木構造を編集する API は全て Node を受け取って Node を返す。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
99 その返ってきた Node をルートノードとして登録することで、木構造の最新のルートノードが更新される。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
100
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
101 updateRootNode は、データベースと木の名前、変更して返ってきた木構造を渡す。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
102
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
103 updateRootNodeをした後は、getRootNodeで取得できるルートノードが更新された状態になっている。
10
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 \begin{lstlisting}[caption=ルートノードの更新]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
106 updateRootNode :: Jungle -> String -> Node -> IO ()
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
107
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
108 updateRootNode jungle "your tree name here" node
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
109 \end{lstlisting}
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 updateRootNodeWithは、ノードを更新する関数とデータベース、木の名前を渡して利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
112 ノードを更新する関数とは、ノードを受け取ってノードを返す関数である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
113 このupdateRootNodeWithを利用することで、getRootNodeをした後、編集しupdateRootNodeを行う一連の操作がatomicallyに行われることが保証される。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
114
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
115 \begin{lstlisting}[caption=関数を渡してルートノードの更新]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
116 updateRootNodeWith :: (Node -> Node) -> Jungle -> String -> IO ()
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
117
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
118 updateRootNodeWith func jungle "your tree name here"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
119 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
120
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
121 \subsubsection{木の編集}
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 木の編集に用いる API は全て Node を受け取って Node を返す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
124 非破壊的木構造を利用しているため、getRootNode などで取得してきた Node は他のスレッドと干渉することなく自由に参照、編集できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
125 これらの編集のためのAPIは、編集後updateRootNodeするか、ひとつの関数にまとめてupdateRootNodeWithをすることで木構造に反映させることができる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
126
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
127 編集対象のノードを指定するには、NodePath を利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
128 NodePath は、ルートノードからスタートし、ノードの子どもの場所を次々に指定したものである。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
129 Haskell の基本データ構造であるリストを利用している。
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
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
132 \begin{figure}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
133 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
134 \includegraphics[width=100mm]{./images/nodepath.pdf}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
135 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
136 \caption{NodePath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
137 \label{fig:nodepath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
138 \end{figure}
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 addNewChildAt で、ノードに新しい子を追加できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
141 addNewChildAt には、Node と NodePath を渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
142 子には Position という場所の情報があるが、インクリメントしながら自動的に指定される。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
143
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
144 \begin{lstlisting}[caption=子の追加]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
145 addNewChildAt :: Node -> Path -> Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
146
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
147 new_node = addNewChildAt node [l,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 deleteChildAt で、ノードの子を削除できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
151 deleteChildAt には、Node と NodePath、削除したい子のPositionを指定する。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
152
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
153 \begin{lstlisting}[caption=子の削除]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
154 deleteChildAt :: Node -> Path -> Position -> Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
155
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
156 new_node = deleteChildAt node [1,2] 0
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
157 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
158
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
159 putAttribute で、ノードに属性を追加できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
160 putAttribute には、Node と NodePath、Key、Valueを渡す。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
161 Key は String、 Value は、ByteString である。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
162
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
163 \begin{lstlisting}[caption=属性の追加]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
164 putAttribute :: Node -> Path -> String -> ByteString -> Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
165
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
166 new_node = putAttribute node [1,2] "key" "value"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
167 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
168
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
169 deleteAttribute で、ノードの属性を削除できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
170 deleteAttribute には、Node と NodePath、Keyを渡す。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
171
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
172 \begin{lstlisting}[caption=属性の削除]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
173 deleteAttribute :: Node -> Path -> String -> Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
174
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
175 new_node = deleteAttribute node [1,2] "key"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
176 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
177
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
178
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
179 \subsubsection{木の参照}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
180 木の参照にも Node を用いる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
181 様々な参照の API があるため、ひとつずつ紹介していく。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
182
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
183 getAttributes は、対象の Path に存在する属性を Key を用いて参照できる。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
184
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
185 \begin{lstlisting}[caption=属性の取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
186 getAttributes :: Node -> Path -> String -> Maybe ByteString
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
187
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
188 bytestring = getAttributes node [1,2] "key"
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
189 \end{lstlisting}
2
d8b94e828d79 add tex files
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
191 あるNodeに存在する全ての子に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
192 getChildren は、対象の Node が持つ全ての子を Node のリストとして返す
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
193
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
194 \begin{lstlisting}[caption=対象のNodeの全ての子を取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
195 getChildren :: Node -> Path -> [Node]
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
196
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
197 nodelist = getChildren node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
198 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
199
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
200 あるNodeに存在する全ての子に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
201 getChildren と違い、子のPositionも取得できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
202 assocsChildren は、対象の Node が持つ全ての子を Position とのタプルにし、そのタプルのリストを返す。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
203
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
204 \begin{lstlisting}[caption=対象のNodeの全ての子とPositionを取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
205 assocsChildren :: Node -> Path -> [(Int, Node)]
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
206
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
207 nodelist = assocsChildren node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
208 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
209
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 あるNodeに存在する全ての属性に対して、参照を行いたい場合に利用する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
212 assocsAttribute は、対象の Node が持つ全ての属性を、Key と Value のタプルとし、そのタプルのリストを返す。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
213
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
214 \begin{lstlisting}[caption=対象のNodeの全てのAttributeのKeyとValueを取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
215 assocsAttribute :: Node -> Path -> [(String, B.ByteString)]
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
216
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
217 attrlist = assocsAttribute node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
218 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
219
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
220 numOfChild では、対象の Node が持つ子どもの数を取得できる。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
221
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
222 \begin{lstlisting}[caption=対象のNodeの子どもの数を取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
223 numOfChild :: Node -> Path -> Int
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
224
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
225 num = numOfChild node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
226 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
227
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
228 currentChild では、対象の Node が持つ最新の子を取得できる。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
229
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
230 \begin{lstlisting}[caption=対象のNodeの最新の子を取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
231 currentChild :: Node -> Path -> Maybe Node
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
232
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
233 node = currentChild node [1,2]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
234 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
235
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
236 \subsubsection{並列実行}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
237 木構造データベース Jungle は、並列に実行することができる。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
238 アプリケーション側で、データベースを参照や変更する際に各スレッドから呼び出しても問題ない。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
239 利用方法も、シングルスレッドで実行する場合と同じである。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
240
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
241 \clearpage
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
242 \section{木構造データベース Jungle の実装}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
243 \subsubsection{開発環境}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
244 実装には、Haskell を用いる。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
245 コンパイラは、Haskell の並列実行に対応した Glasgow Haskell Compiler (GHC) を用いる。
25
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 24
diff changeset
246 GHC は、Haskell で最も広く使われているコンパイラである\cite{ghc}。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
247 並列実行のためのMonadや、スレッドセーフな参照型を提供している。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
248
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
249 \subsection{Jungle}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
250 Jungle は木構造の集まりを表現する。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
251 木には名前がついており、ルートノードの情報も一緒に保持している。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
252
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
253 \subsubsection{木の取り扱い}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
254 Jungle の木の取り扱いには、Haskell の Data.Map を利用している。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
255
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
256 Haskell で連想配列を扱いたい場合、平衡木によって実装された Data.Map を一般的に用いる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
257 Haskell のライブラリには配列や、ハッシュ・テーブルといったものも存在するがあまり使われない。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
258 配列は参照に適しているが、データを追加する際に配列を再作成するためコストが大きい。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
259 ハッシュ・テーブルは更新操作に副作用を伴うため、IOモナドの中でしか使うことが出来ず、扱いにくい。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
260 Data.Mapは、挿入や参照が O(log n) で済む。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
261
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
262 また、木の取り扱いには Haskell のソフトウェア・トランザクショナル・メモリ (STM) を利用して状態を持たせ、スレッド間で共有できるようにしてある。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
263 これは、各スレッドから木構造を新たに作成できるようにするためである。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
264 STM は、スレッド間でデータを共有するためのツールである。STM を利用することでロック忘れによる競合状態や、デッドロックといった問題から解放される。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
265
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
266 \begin{lstlisting}[label=src:node, caption=Treeのデータ型の定義]
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
267 data Jungle = Jungle { getJungleMap :: (TVar (Map String Tree)) }
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
268 \end{lstlisting}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
269
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
270 TVar というのは、Transactional variablesの略で、STM で管理する変数に対して利用する。
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
271
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
272 \subsection{Tree}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
273 Jungleが保持する木構造は、内部的には Tree というデータ型で保持している。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
274 Tree は木の名前と、ルートノードの情報を持っている。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
275 実際にユーザがJungleを利用する際は、Jungle と木の名前を使ってルートノードを取ってくるため、Tree という構造は見えない。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
276
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
277 ルートノードの情報はスレッド間で状態を共有する必要がある。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
278 スレッドセーフに取り扱う必要があるため、この情報も Haskell の ソフトウェア・トランザクショナル・メモリ (STM) を用いて管理している。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
279
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
280 \begin{lstlisting}[label=src:node, caption=Treeのデータ型の定義]
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
281 data Tree = Tree
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
282 { rootNode :: (TVar Node)
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
283 , treeName :: String }
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
284 \end{lstlisting}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
285
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
286 \subsection{Node}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
287 Node は木構造を表現するデータ構造である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
288 再帰的に定義されている。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
289 各ノードは Children としてノードを複数持つことができる(図\ref{fig:node_components})。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
290
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
291 \begin{figure}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
292 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
293 \includegraphics[width=110mm]{./images/node_component.pdf}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
294 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
295 \caption{Nodeの構成要素}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
296 \label{fig:node_components}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
297 \end{figure}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
298
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
299 Children および Attributes も Data.Map を用いて定義されている(ソースコード \ref{src:node})。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
300
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
301 \begin{lstlisting}[label=src:node, caption=Nodeのデータ型の定義]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
302 data Node = Node
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
303 { children :: (Map Int Node)
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
304 , attributes :: (Map String ByteString) }
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
305 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
306
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
307
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
308 \clearpage
20
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
309 \section{Haskellの並列処理}
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
310 純粋関数型言語 Haskell は並列処理に向いていると言われる。
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
311 しかしながら、安直にそう言い切ることはできない。
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
312 参照透過性があるため、各々の関数の処理は独立している。
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
313 そのため、並列で走らせても問題ないように思われるが、Haskell は遅延評価を行うため問題が発生する。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
314 遅延評価では、結果が必要になるまで評価されない。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
315 実装においては、deepseqを用いて即時評価を挟むか、出力など計算が必要となる処理を挟むようにする。
20
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
316
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
317 Haskellでは、様々な並列化手法が提供されている。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
318 スレッドを直接操作することも可能である。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
319
20
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
320 本研究では、抽象度の高い Eval モナドを利用した。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
321 Eval モナドを利用することで、並列処理のために必要な処理の流れを分かりやすく記述することができた。
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
322 しかしながら Eval モナドは実行順序を細かく制御することはできない。
20
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
323 Par モナドを利用すれば、並列処理の流れを細かく記述できるが、
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
324 Eval モナドのように処理と並列処理の流れを分けて記述し、後からプログラムに並列処理を組み込むというようなことはできない。
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
325
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
326 Haskellで並列処理を実装する場合は、どの並列化手法を採用するかということをよく考察する必要がある。
ff03e6179f19 describe the design.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 10
diff changeset
327
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
328 \section{Haskell の生産性}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
329 Java を用いた Jungle の実装と比較して、コード行数が約 3000 行から約 300 行へと短くなった。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
330
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
331 これは Haskell の表現力が高いためである。
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
332 Haskell では、独自のデータ型を簡単に作成することができる。
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
333 再帰的なデータ構造の定義も容易である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
334 共通の性質を扱うための型クラスという仕組みが存在し、既存のライブラリを作成したデータ型に利用できる。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
335 また、Haskellは参照透過性を持つため、コードの再利用が行い易く、関数同士の結合も簡単である。
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
336
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
337 同じような機能を実装する場合でも、Java と比較してコード行数が短くなり生産性が向上する。