annotate paper/chapter3.tex @ 60:79d168016df4

add memorize
author Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
date Tue, 11 Feb 2014 22:58:43 +0900
parents 0a8d66c9ccd1
children d11f4c6c7657
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
43
aa6de0f67a0a add files
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 42
diff changeset
1 \chapter{Haskellによる\\並列データベースの実装}\label{ch:impl}
48
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2  本章では, 並列データベース Jungle の実装について述べる.
10
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 \section{木構造データベース Jungle}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
5 非破壊的木構造データベース Jungle は, Haskell で実装された並列データベースである.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
6 非破壊的木構造の方法に則った関数を提供する.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
7
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
8 % 本研究では, HTTP サーバ Warp と組み合わせて掲示板システムとして利用しているが, 他のシステムに組み込むことも可能である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
9 Jungle の基本的な使い方の手順について説明する.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
10 \begin{enumerate}
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
11 \item{木構造を保持する Jungle を作成する}
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
12 \item{Jungle 内に新しい木を名前をつけて作成する}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
13 \item{木の名前を用いて, ルートノードの取得を行い, データを参照する}
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
14 \item{もしくは, 木の名前を用いて, ルートノードの更新を行う}
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
15 \end{enumerate}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
16
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
17 \subsubsection{Jungle が持つデータ型}
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
18 非破壊的木構造データベース Jungle が持つのデータ型を表\ref{tab:components}に表す.
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
19 また, データ型内部のデータ構造を表\ref{tab:components2}に表す.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
20
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
21 木構造の集まりを表現する Jungle, 単体の木構造を表現する Tree がある.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
22 Node は子と属性を任意の数持てる.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
23 データ型として定義することで, 内部の型の整合性が保たれる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
24 例えば, Node の1つ目の型は (Map Int Node) となり他の型は許されない.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
25 非破壊的木構造データベース Jungle のデータ型について, ひとつずつ説明する.
35
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 34
diff changeset
26
34
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 \begin{center}
48
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
29 \begin{tabular}{|c||c|c|} \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
30 型名 & 概要 \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
31 Jungle & 木の作成・取得を担当する. \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
32 Tree & 木の名前とルートノードの情報を保持している. \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
33 Node & 基本的なデータ構造, 子と属性を任意の数持てる. \\ \hline
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
34 \end{tabular}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
35 \end{center}
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
36 \label{tab:components}
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
37 \caption{Jungle が持つデータ型}
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
38 \end{table}
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
39
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
40 \newpage
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
41 \begin{table}[htbp]
48
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
42 \begin{center}
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
43 \begin{tabular}{|c||c|} \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
44 型名 & データ構造 \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
45 Jungle & Jungle (TVar (Map String Tree)) \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
46 Tree & Tree (TVar Node) String \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
47 Node & Node (Map Int Node) (Map String ByteString) \\ \hline
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
48 \end{tabular}
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
49 \end{center}
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
50 \label{tab:components2}
48
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
51 \caption{データ型のデータ構造}
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
52 \end{table}
88b11a3afb93 describe deos
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
53
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
54 \clearpage
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
55 \section{Jungle}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
56 Jungle は木構造の集まりを表現する.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
57 木には名前がついており, Tree の情報と一緒に保持している(ソースコード\ref{src:jungle}).
35
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 34
diff changeset
58
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
59 \begin{lstlisting}[label=src:jungle, caption=Jungleのデータ型の定義]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
60 data Jungle = Jungle { getJungleMap :: (TVar (Map String Tree)) }
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
61 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
62
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
63 Jungle のデータ構造は, Jungle (TVar (Map String Tree)) である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
64 getJungleMap :: というのは, Haskell のレコード構文である.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
65
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
66 レコード構文は, データ構造へのアクセサを提供する.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
67 getJungleMap は関数で, ソースコード\ref{src:getjunglemap}の型を持つ.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
68 これは, Jungleを受け取って, TVar (Map String Tree)を返す関数である.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
69
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
70 レコード構文はデータ型を受け取って, :: の右側の型の値を取り出せる関数を作成すると思えば良い.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
71
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
72 \begin{lstlisting}[label=src:getjunglemap, caption=getJungleMap]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
73 getJungleMap :: Jungle -> TVar (Map String Tree)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
74 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
75
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
76 Jungle の木の取り扱いには, Haskell の Data.Map を利用している.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
77 型名は, Map である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
78 Map は, 連想配列を扱うことのできるデータ構造である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
79 平衡木を用いて, 挿入や参照が O (log n)で済むように設計されている.
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
80 Data.Mapを理解するためにはリストで考えると分かりやすい(ソースコード\ref{src:map_list}).
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
81
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
82 \begin{lstlisting}[label=src:map_list, caption=リストで定義した場合のMap]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
83 data Map k a = Map [(k,a)]
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
84
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
85 lookup' :: Eq k => k -> Map k a -> Maybe a
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
86 lookup' k (Map []) = Nothing
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
87 lookup' k (Map ((k',a):xs)) = if k == k'
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
88 then Just a
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
89 else lookup k xs
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
90
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
91
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
92 insert :: k -> a -> Map k a -> Map k a
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
93 insert k a (Map x) = Map ((k,a):x)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
94
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
95 test = Map [("key","value"),("fizz","buzz")]
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
96 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
97
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
98 Map は, キーと値のペアのリストだと考えることができる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
99 キーが一致する値を探す場合, lookup'を用いる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
100 Maybe モナドを用いて, データがなければ Nothing, データがあれば Just に包んで返す.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
101 $=>$ の前にある, Eq kは, 型クラスの制約である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
102 内部で k と k' の同値性をテストしているため, k は同値性をチェックできる型クラス Eq に属している型である必要がある.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
103
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
104 新たにキーと値のペアを, Mapに追加するには insertを用いる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
105 Haskell では, 受け取った引数を変更することができないため, ペアを追加した新しい Map を返す.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
106
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
107 木の取り扱いには Haskell のソフトウェア・トランザクショナル・メモリ (STM) を利用して状態を持たせ, スレッド間で共有できるようにしてある.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
108 これは, 各スレッドから木構造を新たに作成できるようにするためである.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
109 STM は, スレッド間でデータを共有するためのツールである. STM を利用することでロック忘れによる競合状態や, デッドロックといった問題から解放される.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
110 Jungle のデータ構造の Map の前に付いている TVar というのは, Transactional variablesの略で, STM で管理する変数に対して利用する.
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
111
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
112 \subsubsection{Jungle と木の作成}
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
113 Jungle は, 複数の非破壊的木構造を持つため, Map で木を管理している(図\ref{fig:jungle}).
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
114 Tree には名前がついており, 複数のバージョンの Tree のノードのどれが最新かという情報を持っている.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
115
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
116 \begin{figure}[!htbp]
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
117 \begin{center}
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
118 \includegraphics[scale=0.7]{./images/jungle_type.pdf}
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
119 \end{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
120 \caption{複数の木を扱えるJungle}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
121 \label{fig:jungle}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
122 \end{figure}
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
123
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
124 木構造の識別, つまり Map の キー にはString を利用する.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
125 String は Haskell の文字列の型で, Char のリスト [Char] の別名である.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
126
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
127 Jungle を作成するには, createJungle を用いる(ソースコード\ref{src:createJungle}).
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
128 empty は空のMapを作成する関数である.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
129
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
130 \begin{lstlisting}[label=src:createJungle, caption=createJungle]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
131 createJungle :: IO Jungle
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
132 createJungle = atomically $ do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
133 map <- newTVar empty
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
134 return (Jungle map)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
135 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
136
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
137
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
138 createJungleは, 新たにSTMの変数を作成する newTVar を実行する.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
139 newTVar などの STM の操作は STM モナド内で行う.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
140 最後にatomicallyを行うことで, do 構文内がトランザクションとして実行される.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
141 STMの関数が持つ型をソースコード\ref{src:stm}に示す.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
142
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
143 \begin{lstlisting}[label=src:stm, caption=STMの関数]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
144 newTVar :: a -> STM (TVar a)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
145 readTVar :: TVar a -> STM a
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
146 writeTVar :: TVar a -> a -> STM ()
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
147
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
148 atomically :: STM a -> IO a
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
149 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
150
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
151 ソースコード\ref{src:createJungle}の atomically の隣にある \$ は関数適用演算子である.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
152 \$ 関数は最も低い優先順位を持っており, 右結合である.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
153 括弧を減らすのに使う. \$ を使わない場合はソースコード\ref{src:dollar}の様に記述することになる.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
154
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
155 \begin{lstlisting}[label=src:dollar, caption=関数適用演算子を使わない場合]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
156 createJungle :: IO Jungle
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
157 createJungle = atomically (do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
158 map <- newTVar empty
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
159 return (Jungle map))
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
160 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
161
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
162 createJungle は, IOを返すため使う際には main に関連付ける必要がある.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
163
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
164 \clearpage
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
165 \section{Tree}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
166 Jungleが保持する木の情報は, 内部的には Tree というデータ型で保持している.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
167 Tree は木の名前と, ルートノードの情報を持っている(ソースコード\ref{src:tree}).
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
168 実際にユーザがJungleを利用する際は, Jungle と木の名前を使ってルートノードを取ってくるため, Tree という構造は見えない.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
169
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
170 ルートノードの情報はスレッド間で状態を共有する必要がある.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
171 スレッドセーフに取り扱う必要があるため, この情報も Haskell の ソフトウェア・トランザクショナル・メモリ (STM) を用いて管理している.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
172
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
173 \begin{lstlisting}[label=src:tree,caption=Treeのデータ型の定義]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
174 data Tree = Tree
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
175 { rootNode :: (TVar Node)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
176 , treeName :: String }
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
177 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
178
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
179 新たな非破壊的木構造を作るには, createTree を用いる(ソースコード\ref{src:createTree}).
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
180 createTree は, createJungleで作成した Jungle と木の名前を String で受け取る.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
181
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
182 \begin{lstlisting}[label=src:createTree, caption=createTree]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
183 createTree :: Jungle -> String -> IO ()
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
184 createTree (Jungle tmap) tree_name = atomically $ do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
185 map <- readTVar tmap
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
186 tree <- emptyTree tree_name
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
187 writeTVar tmap (insert tree_name tree map)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
188
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
189 emptyTree :: String -> STM Tree
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
190 emptyTree tree_name = do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
191 node <- newTVar emptyNode
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
192 return (Tree node tree_name)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
193
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
194 emptyNode :: Node
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
195 emptyNode = Node (empty) (empty)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
196 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
197
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
198 createJungleも STM を操作するため IOを返す.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
199 Jungle の持つ, 複数の木構造と名前を関連付けた Map をreadTVarで取得する.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
200 ルートノードの管理のための STM の変数をもった Tree を作成し, Jungle の Map に insert する.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
201 そして最後に writeTVar を用いて STM を更新する.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
202 writeTVar は更新する先の変数と, 更新内容の2つを受け取る STM の関数である.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
203
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
204 実際にcreateJungleとcreateTreeを利用する時はソースコード\ref{src:createdatabase}のように記述する.
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
205
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
206 \begin{lstlisting}[label=src:createdatabase,caption=データベースと木の作成]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
207 main = do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
208 jungle <- createJungle
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
209 createTree jungle "name of new tree here"
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
210 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
211
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
212
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
213 \subsubsection{ルートノード}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
214 非破壊的木構造データベース Jungle では, 木の最新の状態を更新・参照するのにルートノードを使う.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
215 ルートノードは, 最新の木構造の根がどれかの情報を保持している(図\ref{fig:getrootnode}).
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
216
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
217 \begin{figure}[!htbp]
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
218 \begin{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
219 \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
220 \end{center}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
221 \caption{ルートノード}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
222 \label{fig:getrootnode}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
223 \end{figure}
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
224
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
225 ルートノードに関する関数を説明する.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
226 getRootNode は, 最新のルートノードを取得できる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
227 データベースと木の名前を渡すことで利用できる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
228 例えば, 図\ref{fig:getrootnode}の状態の時は, B というルートノードが取得できる.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
229
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
230
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
231 getRootNode 関数の定義を示す(ソースコード\ref{src:getrootnode}).
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
232 まず, readTVarでJungleが持つmapを参照する.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
233 Haskell の where キーワードは, 計算の中間結果に名前をつけるために用いられる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
234 今回は, root\_node という map を受け取る関数を定義している.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
235 root\_node map では, Jungle が持つ Map をみて取得しようとしている名前の木構造があるかどうか調べている.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
236 木構造があった場合, rootNodeというTreeに定義されているレコード構文のアクセサ関数を使って, (TVar Node)を取得する.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
237 最後に, (TVar Node)に対して, readTVarを行うことで最新のルートノードが取得できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
238
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
239 \begin{lstlisting}[label=src:getrootnode, caption=最新のルートノードの取得]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
240 getRootNode :: Jungle -> String -> IO Node
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
241 getRootNode (Jungle tmap) tree_name = atomically $ do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
242 map <- readTVar tmap
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
243 readTVar (root_node map)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
244 where
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
245 root_node map = case lookup tree_name map of
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
246 Just x -> rootNode x
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
247 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
248
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
249 木構造を編集する関数は全て Node を受け取って Node を返す.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
250 その返ってきた Node をルートノードとして登録することで, 木構造の最新のルートノードが更新される.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
251 updateRootNode は, データベースと木の名前, 変更して返ってきた木構造の 3 つを渡す.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
252 updateRootNodeをした後は, getRootNodeで取得できるルートノードが更新された状態になっている.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
253
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
254 updateRootNode 関数の定義を示す(ソースコード\ref{src:updaterootnode}).
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
255 getRootNodeと同じように, Treeの(TVar Node)を取得し, 最後にwriteTVarを用いて更新している.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
256
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
257 \begin{lstlisting}[label=src:updaterootnode, caption=ルートノードの更新]
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
258 updateRootNode :: Jungle -> String -> Node -> IO ()
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
259 updateRootNode (Jungle tmap) tree_name node =
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
260 atomically $ do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
261 map <- readTVar tmap
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
262 writeTVar (root_node map) node
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
263 where
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
264 root_node map = case lookup tree_name map of
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
265 Just x -> rootNode x
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
266 \end{lstlisting}
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
267
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
268 updateRootNodeWithは, ノードを更新する関数とデータベース, 木の名前を渡して利用する.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
269 ノードを更新する関数とは, ノードを受け取ってノードを返す関数である. (Node $->$ Node) がそれにあたる.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
270 このupdateRootNodeWithを利用することで, getRootNodeをした後に編集しupdateRootNodeを行う一連の操作が分断されずに行われることが保証される.
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
271
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
272 updateRootNodeWith 関数の定義を示す(ソースコード\ref{src:updaterootnodewith}).
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
273 updateRootNodeWithでは, 一連の操作を分断せずに行うためにreadTVarからwriteTVarまで同じ STM モナド内で行っている.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
274 atomicallyに関数にdo構文で繋げたSTMモナドを渡すことで, このブロックがトランザクションとして実行される.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
275
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
276 \begin{lstlisting}[label=src:updaterootnodewith, caption=ルートノードの更新]
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
277 updateRootNodeWith :: (Node -> Node) -> Jungle -> String -> IO ()
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
278 updateRootNodeWith f (Jungle tmap) tree_name =
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
279 atomically $ do
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
280 map <- readTVar tmap
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
281 n <- readTVar (root_node map)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
282 writeTVar (root_node map) (f n)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
283 where
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
284 root_node map = case lookup tree_name map of
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
285 Just x -> rootNode x
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
286 \end{lstlisting}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
287
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
288 並列データベース Jungle で他のスレッドと状態を共有する操作は,
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
289 createJungle, createTree, getRootNode, updateRootNode, updateRootNodeWith
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
290 で全てである.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
291 並列データベース Jungle では, なるべく状態を共有しないようにすることで並列実行時の性能の向上を実現する.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
292 ソフトウェアトランザクショナルメモリは書き込み時に他から変更があった場合にやり直しという操作はあるものの, 読み込みに関してはノンブロッキングで高速に読み込める.
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
293
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
294 \clearpage
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
295 \section{Node}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
296 Node は木構造を表現するデータ構造である.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
297 再帰的に定義されている.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
298 各ノードは children として子ノードを複数持つことができる(図\ref{fig:node_components}).
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
299
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
300 \begin{figure}[!htbp]
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
301 \begin{center}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
302 \includegraphics[width=110mm]{./images/node_component.pdf}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
303 \end{center}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
304 \caption{Nodeの構成要素}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
305 \label{fig:node_components}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
306 \end{figure}
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
307
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
308 children および attributes も Data.Map を用いて定義されている(ソースコード \ref{src:node}).
40
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
309
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
310 \begin{lstlisting}[label=src:node, caption=Nodeのデータ型の定義]
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
311 data Node = Node
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
312 { children :: (Map Int Node)
bd30d93097da describe Jungle and Tree
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 35
diff changeset
313 , attributes :: (Map String ByteString) }
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
314 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
315
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
316 \subsubsection{木の編集}
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
317 木の編集には, Node を使う.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
318 木の編集に用いる関数は全て Node を受け取って Node を返す.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
319 非破壊的木構造を利用しているため, getRootNode などで取得してきた Node は他のスレッドと干渉することなく自由に参照, 編集できる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
320 これらの編集のための関数は, 編集後updateRootNodeするか, ひとつの関数にまとめてupdateRootNodeWithをすることで木構造に反映させることができる.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
321
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
322 編集対象のノードを指定するには, NodePath を利用する(図\ref{fig:nodepath}).
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
323 NodePath は, ルートノードからスタートし, ノードの子どもの場所を次々に指定したものである.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
324 Haskell の基本データ構造であるリストを利用している.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
325
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
326 \begin{figure}[!htbp]
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
327 \begin{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
328 \includegraphics[width=100mm]{./images/nodepath.pdf}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
329 \end{center}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
330 \caption{NodePath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
331 \label{fig:nodepath}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
332 \end{figure}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
333
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
334 木の編集を行う関数を紹介する.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
335 木の編集を行う関数の型の定義をソースコード\ref{src:editfunc_type}に示す.
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
336
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
337 \begin{lstlisting}[label=src:editfunc_type, caption=木の編集を行う関数]
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
338 addNewChildAt :: Node -> Path -> Node
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
339 deleteChildAt :: Node -> Path -> Position -> Node
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
340 putAttribute :: Node -> Path -> String -> ByteString -> Node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
341 deleteAttribute :: Node -> Path -> String -> Node
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
342 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
343
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
344 \paragraph*{addNewChildAt}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
345 ノードに新しい子を追加できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
346 更新対象となる木構造の Node と, どこに追加するかの情報である NodePath を渡す必要がある.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
347 子の場所は, インクリメントしながら自動的に指定される.
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
348
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
349 \paragraph*{deleteChildAt}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
350 ノードの子を削除できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
351 更新対象となる木構造の Node と, どこのノードの子を削除するかという情報である NodePath, 削除したい子の場所を指定する Position を渡す必要がある.
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
352
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
353 \paragraph*{putAttribute}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
354 ノードに属性を追加できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
355 更新対象となる木構造の Node と, どこに属性を追加するかの情報である NodePath を渡す必要がある.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
356 属性はキーと値があり, キーは String, 値は ByteString である.
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
357
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
358 \paragraph*{deleteAttribute}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
359 ノードの属性を削除できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
360 更新対象となる木構造の Node と, どこの属性を削除するかの情報である NodePath, 削除したい属性のキーである String を渡す必要がある.
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
361
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
362 これらの関数は, ほぼ同一の関数で定義できる.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
363 addNewChildAtを用いて説明する(ソースコード\ref{src:addNewChildAt}).
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
364
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
365 \newpage
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
366 \begin{lstlisting}[label=src:addNewChildAt, caption=木の編集を行う関数]
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
367 addNewChildAt :: Node -> Path -> Node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
368 addNewChildAt parent [] = addChildAt parent emptyNode
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
369 addNewChildAt parent (x:xs) = addChild parent x $ addNewChildAt x_node xs
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
370 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
371 map = children parent
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
372 x_node = case lookup x map of
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
373 Just x -> x
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
374
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
375 addChild :: Node -> Position -> Node -> Node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
376 addChild node pos child = Node new_child attr
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
377 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
378 map = children node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
379 new_child = insert pos child map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
380 attr = attributes node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
381
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
382 addChildAt :: Node -> Node -> Node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
383 addChildAt node child = Node new_child attr
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
384 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
385 map = children node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
386 pos = (size map) + 1
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
387 new_child = insert pos child map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
388 attr = attributes node
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
389 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
390
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
391 非破壊的木構造の編集は再帰で定義できる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
392 左結合となる\$を使い, 対象のノードに到達するまで, addChildを繰り返す.
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
393 addChildは, 指定したノードのPositionに子を追加する. 引数として子となるノードが必要である.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
394 addChildを繰り返すことで, 下の階層から徐々に上に作られていく.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
395
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
396 addNewChildAt, deleteChildAt, putAttribute, deleteAttributeといった,
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
397 非破壊的木構造の編集は, 対象のノードに対する操作以外は全て同じである.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
398 Pathのリストが空になる, すなわち対象のノードに到達した時の操作だけが異なる.
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
399 新しい子を追加するのが addNewChildAt, 指定されたポジションの子を削除するのが deleteChildAt,
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
400 指定されたキーと値を追加するのが putAttribute, 指定されたキーの値を削除するのが deleteAttributeである.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
401
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
402 \subsubsection{木の参照}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
403 木の参照にも参照対象となる木構造の Node を用いる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
404 参照関数の定義をソースコード\ref{src:reffunc}に示す.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
405
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
406 \begin{lstlisting}[label=src:reffunc, caption=参照関数]
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
407 getNode :: Node -> Path -> Node
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
408 getNode node [] = node
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
409 getNode node (x:xs) = getNode child xs
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
410 where
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
411 map = children node
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
412 child = case M.lookup x map of
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
413 Just x -> x
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
414 getAttributes :: Node -> Path -> String -> Maybe ByteString
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
415 getAttributes node path key = lookup key map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
416 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
417 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
418 map = attributes target
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
419
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
420 getChildren :: Node -> Path -> [Node]
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
421 getChildren node path = elems map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
422 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
423 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
424 map = children target
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
425
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
426 assocsChildren :: Node -> Path -> [(Int, Node)]
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
427 assocsChildren node path = assocs map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
428 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
429 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
430 map = children target
2
d8b94e828d79 add tex files
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
432 assocs :: Node -> Path -> [(String, ByteString)]
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
433 assocs node path = assocs map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
434 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
435 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
436 map = attributes target
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
437
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
438 numOfChild :: Node -> Path -> Int
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
439 numOfChild node path = size map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
440 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
441 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
442 map = children target
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
443
41
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
444 currentChild :: Node -> Path -> Maybe Node
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
445 currentChild node path = lookup pos map
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
446 where
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
447 target = getNode node path
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
448 map = children target
5b69636936cc add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
449 pos = size map
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
450 \end{lstlisting}
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
451
60
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
452 参照関数の基本的な流れは, getNode関数を使って参照したいPathのノードを取ってくることである.
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
453 そのノードにはwhereキーワードを利用して, targetという名前をつけている.
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
454 targetに対して, 子のMapや属性のMapを取得した後, lookup関数などを適用する.
79d168016df4 add memorize
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 49
diff changeset
455 elems, assocs, sizeなどはData.Mapの参照関数で, Jungle ではその関数をそのまま利用している.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
456
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
457 参照関数の基本的な機能をまとめて説明する.
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
458
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
459 \paragraph*{getAttributes}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
460 対象の Path に存在する属性を Key を用いて参照できる.
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
461
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
462 \paragraph*{getChildren}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
463 対象の Node が持つ全ての子を Node のリストとして返す.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
464 あるNodeに存在する全ての子に対して, 参照を行いたい場合に利用する.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
465
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
466 \paragraph*{assocsChildren}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
467 対象の Node が持つ全ての子を Position とのタプルにし, そのタプルのリストを返す.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
468 あるNodeに存在する全ての子に対して, 子のPositionを取得しながら参照を行いたい場合に利用する.
34
345eacdf29e4 add apendix
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 25
diff changeset
469
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
470 \paragraph*{assocsAttribute}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
471 対象の Node が持つ全ての属性を, キーと値のペアとし, そのペアのリストを返す.
47
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 43
diff changeset
472 あるNodeに存在する全ての属性に対して, 参照を行いたい場合に利用する.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
473
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
474 \paragraph*{numOfChild}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
475 対象の Node が持つ子どもの数を取得できる.
10
a349b2c01cfe add graffle
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
476
49
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
477 \paragraph*{currentChild}
0a8d66c9ccd1 describe the impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 48
diff changeset
478 対象の Node が持つ最新の子を取得できる.
23
73a8440dcbff add impl
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
479