view paper/sigos.tex @ 4:0c8bb16afb8d

sigos_ver2
author suruga
date Thu, 20 Apr 2017 23:50:20 +0900
parents 07a31c08d082
children bec6eb1e0297
line wrap: on
line source

%\documentclass[a4j,12pt]{jreport}
\documentclass[techrep]{ipsjpapers}
%\documentclass{jarticle}
\usepackage[dvipdfmx]{graphicx}
\usepackage{url}
\usepackage{listings,jlisting}
\usepackage{enumitem}
%\usepackage{comment} 
%コメントアウト用package


\lstset{
    language=C, 
    tabsize=2, 
    frame=single, 
    basicstyle={\ttfamily\footnotesize},% 
    identifierstyle={\footnotesize},% 
    commentstyle={\footnotesize\itshape},% 
    keywordstyle={\footnotesize\bfseries},% 
    ndkeywordstyle={\footnotesize},% 
    stringstyle={\footnotesize\ttfamily}, 
    breaklines=true, 
    captionpos=b, 
    columns=[l]{fullflexible},% 
    xrightmargin=0zw,% 
    xleftmargin=1zw,% 
    aboveskip=1zw, 
    numberstyle={\scriptsize},% 
    stepnumber=1, 
    numbersep=0.5zw,% 
    lineskip=-0.5ex, 
}
\renewcommand{\lstlistingname}{Code}

\input{dummy.tex} %% Font 

% ユーザが定義したマクロなど.
\makeatletter

\begin{document}

% 和文表題
\title{Code Gear、 Data Gear に基づく OS のプロトタイプ}
% 英文表題
\etitle{}

% 所属ラベルの定義
\affilabel{1}{琉球大学大学院理工学研究科情報工学専攻 \\Interdisciplinary Information Engineering, Graduate School of Engineering and Science, University of the Ryukyus.}
\affilabel{2}{琉球大学工学部情報工学科\\Information Engineering, University of the Ryukyus.}

% 和文著者名
\author{
    仲松 栞\affiref{1}
  \and
    照屋 のぞみ \affiref{2}
  \and
    河野 真治\affiref{2}
}

% 英文著者名
\eauthor{
    Nakamatsu Shiori\affiref{1}
  \and
    eruya Nozomi\affiref{2}
  \and
    Shinji KONO\affiref{2}
}

% 連絡先(投稿時に必要.製版用では無視される.)
\contact{仲松 栞\\
        〒903-0213 沖縄県西原町千原1番地\\
	琉球大学工学部情報工学科\\
        TEL: (098)895-2221\qquad FAX: (098)895-8727\\
        email: innparusu@cr.ie.u-ryukyu.ac.jp}

% 和文概要
\begin{abstract}
   
\end{abstract}

% 英文概要
\begin{eabstract}
\end{eabstract}

% 表題などの出力
\maketitle

% 本文はここから始まる

% Introduce
\section{研究目的と背景}

\section{非破壊的木構造データベースJungle}
  Jungleは、当研究室で開発を行っている非破壊的木構造データベースで、Javaを用いて実装さ
れている。非破壊的木構造とは、データの編集を一度生成した木を上書きせず、ルートから編集を行う位置までのノードをコピーする特徴を持つ(図\ref{fig:non_destructive_tree} )。これにより、読み込み中にデータが変更されないことが保証されているため、書き込みと読み込みを同時に行うことできる。
  %木のルートをAtomicに置き換えることで、木のアップデートを行う。変更前の木が残っているので、そのまま使用できる。変更されないノードは変更前と変更後のルートから共有されることになる。
\begin{figure}[ht]
        \begin{center}
            \includegraphics[width=60mm]{./pic/non_destructive_tree.pdf}
        \end{center}
        \caption{非破壊的木構造の編集}
        \label{fig:persistent_data_tree}
\end{figure}
 Jungleは名前付きの複数の木の集合からなり、木は複数のノードの集合でできている。ノードは自身の子のリストと属性名、属性値を持ち、データベースのレコードに相応する。通常のレコードと異なるのは、ノードに子供となる複数のノードが付くところである。Jungleでは、子供からの親へのポインタは持たないため、親から子への片方向の参照しかできない。
 通常のRDBと異なり、Jungleは木構造をそのまま読み込むことができる。例えば、XMLやJsonで記述された構造を、データベースを設計することなく読み込むことが可能である。また、この木を、そのままデータベースとして使用することも可能である。しかし、木の変更の手間は木の構造に依存する。特に非破壊木構造を採用しているJungleでは、木構造の変更の手間はO(1)からO(n)となりえる。つまり、アプリケーションに合わせて木を設計しない限り、十分な性能を出すことはできない。逆に、正しい木の設計を行えば高速な処理が可能である。
 Jungleは基本的にon memoryで使用することを考えており、一度、木のルートを取得すれば、その上で木構造として自由にアクセスして良い。Jungleは分散データベースを構成するように設計されており、分散ノード間の通信は木の変更のログを交換することによって行われる。持続性のある分散ノードを用いることでJungleの持続性を保証することができる。
  
\section{Index}
 Jungleは、非破壊的木構造というデータ構造上、過去の版の木構造を全て保持している。よって、すべての版に独立したIndexが必要となるため、前の版のIndexを破壊すること無く、Indexを更新する必要がある。既存の TreeMap では、一度 Index の複製を行い、その後更新する必要があったため、Indexの更新オーダーがO(n)となっていた。その問題を解決するため、Java 上で関数型プログラミングを行えるライブラリである、 Functional Java の TreeMap を使用し、それを用いて Index 実装を行なった。この TreeMap は、 Jungle と同じようにルートから変更を加えたノードまでの経路の複製を行い、データの更新を行なった際、前の版と最大限データを共有した新しい TreeMap を作成する。Jungle との違いは、木の回転処理が入ることである。これにより複数の版すべてに対応した Index をサポートすることが可能になった。
\section{非破壊TreeMap}
 Jungle の Index は、Functional Java の非破壊 TreeMap を用いて実装を行なっている。しかし、Functional Java の TreeMap は、木の変更の手間が大きい、並列実行処理速度が落ちるなど、実用的な性能を持っていなかった。そのため、Jungleの性能も、TreeMap 部分がネックとなっていた。その問題を解決するため、 Jungle で使用する非破壊 TreeMap を作成した。TreeMap は、Red Black Tree のアルゴリズムを用いている。RedBlackTreeとは二分木探索の一つで、以下の条件を満たした木のことである。
\begin{itemize}
    \item 各ノードは赤か黒の色を持つ。
    \item ルートノードは黒色である。
    \item 全ての葉は黒色である。
    \item 赤いノードの子は黒色である。
    \item 全ての葉からルートノードまでのパスには、同じ個数の黒いノードがある。
\end{itemize}
%ここもうちょっとかく。
\section{Indexの差分Updateの実装}
 Jungleは木の編集を行う際に、編集を行うノードと、経路にあるノードの複製を行い新しい木構造を構築するため、 Index の中には、編集後の木には存在しない複製前のノードが残ってしまう。なので、 Index の差分 Update を行う際には、それらのノードを Index から削除して、新しく複製されたノードを Index に登録する必要がある。
 そのためには、編集を行なったノードを覚えておく必要がある。そこで、 Jungle Tree Editor 内に、編集を加えたノードを覚えておくためのリストを定義した。 Editor は木に編集を加えた際、リストに編集前のノードを保存する。そして、Commit 時にリストにあるノードを使って Index の中に残っている、編集後の木に存在しないノードを削除する。その後、新しく作られたノードを Index に登録して Update は終了する。


\paragraph* {編集前ののノードの削除}
ndex のUpdate を行う際、初めに、編集後の木に存在しないノードを Index から削除する。削
除の対象は、変更を加えたノードと、ルートから変更を加えたノードまでの経路にあるノード
である。ノードの削除は、以下の手順で行われる。
 \begin{itemize}
    \item 編集を行なったノードのリストからノードを取得する。
    \item 取得したノードが、保持している値をIndex から削除する。
    \item  自身と子供のペアを Parent Index から削除する。
    \item  ParentIndex から親を取得する。
    \item  2 - 4 をルートノードにたどり着くか、 ParentIndex から親を取得できなkなるまで続ける。
    \item 1 - 5 をリストからノードが無くなるまで続ける。
\end{itemize}
 Parent Index に現在のノードが登録されていない場合は、現在のノードからルートまでの経路にあるノードはIndexから削除されているため、削除を終えて、リストに入っている次のノードの削除処理を行なっても構わない。

\paragraph* {Indexへのノードの挿入}
Index から不要なノードを削除した後は、木の編集時新しく作られたノードを Index に挿入する。ノードの挿入は、以下の手順で行われる。
 \begin{itemize}
    \item 木からルートノードを取得する
    \item 取得したノードがIndex に登録されているかを調べる。
    \item 登録されている場合、そのノード以下の Sub treeは、全てIndexに登録されているので、次のノードに移動する。
    \item  登録されていなかった場合、自身が保持している値をIndex に登録する。
    \item  自身と子ノードを Parent Index に登録する。
    \item 自身の子ノードを取得したノードとして2に戻る。
    \item 全てのノードを登録したら終了する。
\end{itemize}
    
\section{Differential Jungle Treeの実装}
  Jungleは木の編集時、ルートから編集を行う位置までのノードの複製を行う。そのため、木の編集の手間は、木構造の形によって異なる。特に線形の木は、全てのノードの複製を行うため、変更の手間がO(n)になってしまう。そこで、Jungleは、線形の木をO(1)で変更するPushPop の機能を持つ。PushPop とは、ルートノードの上に新しいルートノードを付け加える API である(図\ref{fig:PushPopDemerit} )。すると、木の複製を行う必要が無いため、木の変更の手間がO(1)でノードの追加を行える。
 \begin{figure}[ht]
    \begin{center}
        \includegraphics[width=70mm]{./pic/PushPopDemerit.pdf}
    \end{center}
    \caption{PushPop}
    \label{fig:PushPopDemerit}
\end{figure}
 しかし、PushPopはルートノードを追加していくため、図\ref{fig:PushPopDemerit} のようにノードの並びが逆順になってしまう。Logなどの正順の木でなければデータを表現できない場合、木の編集時PushPop を使用できない。そこで、木の編集の手間を O(1) で、正順の木を構築できるDifferential Jungle Tree の実装を行なった。 Differential Jungle Tree は。木のバージョンごとに、自身の木の最後尾を表す末尾ノードを保持する。木の編集は、別途構築したSub Tree に対して破壊的に更新を行い、Commit 時に末尾のノードに Sub Tree を Append することで行う。この場合は木が破壊的に変更されているように見えるが、前の版の末端部分を超えてアクセスすることがなければ複数の版を同時に使用することができる。
  
\paragraph* {Differential Tree Context}
 Jungleの木はTreeContext というオブジェクトに自身の木の情報を保持している。Differential Jungle Tree では、現在の版の木構造の末尾ノードを保持することが可能な Differential Tree Context を作成した。
 
 \paragraph* {Differential Jungle Tree の作成}
  Differential Jungle Tree を作成するためにJungle に、新しいAPIを実装した。表(\ref{table:Differential API})

\begin{table}[htb]
  \begin{center}
  \caption{Jungleに新しく実装したAPI}
    \begin{tabular}{|p{3cm}|p{4cm}|} \hline
    \hline \shortstack{ createNewDifferenceTree\\ (StringtreeName)}&  Jungleに新しくDifferential Jungle Treeを生成する。木の名前が重複した場合、生成に失敗し null を返す。\\ 
    \hline
    \end{tabular}
   \label{table:Diffetential API}
  \end{center}
\end{table}


\paragraph* {末尾ノードを使用した木の編集}
 Differential Jungle Tree の木の編集は、Differential Jungle Tree Editor を使用して行う。 Differential Jungle Tree Editor は、Default Jungle Tree Editor と違い、生成時に新しい木構造(Sub Tree)を自身の中に構築する。そして、木の編集は、Editor が保持している木構造に対して行う。編集後、Commit を行う際に構築した木構造を、 Differential Jungle Tree の末尾ノードにAppend する。その際木の複製は行わない。
 また、Differential Tree は自身が保持している木構造に対する変更しか行えないため、一度Commit した木に対して変更は行えない。図\ref{fig:EditDifferencialTree}
 
\begin{figure}[ht]
    \begin{center}
        \includegraphics[width=70mm]{./pic/EditDifferencialTree.pdf}
    \end{center}
    \caption{末尾ノードを使用した木の編集}
    \label{fig:EditDifferencialTree}
\end{figure}

\begin{itemize}
    \item 木からgetJungleTreeEditor で Editor を取得する。(このとき Editor は新しい木構造(Sub Tree)を持つ)。
    \item Editorが保持している木構造に対して addNewChild(	\textless-1.0\textgreater)を実行し、ノードの追加を行う。
    \item Commit を行い、Treeの末尾ノードにEditorが保持している木構造を Append する。
\end{itemize}
 Editor が保持している木構造に最後に追加したノードが、新しい木の末尾ノードとなる。また、Differential Jungle Tree は、木の編集時複製を行わないため、 Index のアップデートは、 Editor が保持している木構造のデータを Index に追加するだけで良い。
 
 \paragraph* {Differential Jungle Tree の検索}
  Differential Jungle Tree は、末尾ノードを使って、現在の木構造を表現している。なので、過去の木に対して全探索を行なった場合、その版には無いはずのノードが取得できてしまう。例として、編集前の木である Tree ver1 と編集後の木である Tree ver2 があるとする(図\ref{fig:PushPopDemerit})。ここで、Tree ver1 に対して、全探索を行なった場合、本来Tree ver1 に存在しないノード3・4も検索対象に含まれてしまう。そこで、その版の木が持つ末尾ノード以下のSub Tree を検索対象から除外する、Differential Interface Traverser を実装した。Differential Interface Traverserを用いて木の全探索を行なった場合、Tree ver1 に存在しないノード3・4は検索対象から省かれる。
 %画像つくる 
\begin{figure}[ht]
    \begin{center}
        \includegraphics[width=70mm]{./pic/EditDifferencialTree.pdf}
    \end{center}
    \caption{複数の版の木の表現}
    \label{fig:EditDifferencialTree}
\end{figure}
  Index を使用した検索を行う場合、各版の木に対応した Index があるため、Default Tree と検索のアルゴリズムは変わらない。これらの実装により Differential Jungle Tree は木構造の構築・検索を行う。
 
\paragraph* {Differential Jungle Tree の検索}
  Differential Jungle Tree への Commit は、編集後の木のデータを持つ TreeContext を作り、編集前の木が持つ TreeContext と Atomic に入れ替えることで行われる。しかし、Differential Jungle Tree のCommit は、Default Jungle Tree の Commit と異なり、TreeContext の入れ替えと、 Editor が保持している木構造の末尾ノードへの Append の2つのプロセスからなる。 TreeContext の入れ替えに関しては、 Default Jungle Tree と同じように行い、末尾ノードへの Editor が持っている木構造の Append は、TreeContect の入れ替えが成功した後に行う。そうすることで、別Thread で行われている Commit と競合した際に、 TreeContext を入れ替えた Thread と別 Thread がAppend を行い、木の整合性が崩れることを回避している。
  また、過去の版の木に対して、編集を加えCommit を行なった場合、木の整合性が崩れてしまう問題もある。図()()を例に解説する。図()の過去の版の木 Tree ver1 に新しいノード5を追加・Commit を行うと、新しい木 Tree ver'2 が構築される。ここで、Tree ver'2 に対して全検索を行う。differential Jungle Tree に対する全検索は、末尾ノードよ上にあるノードを検索対象にする。しかしノード3・4という、本来存在しないはずのノードが検索対象に含まれてしまう。これは、過去の版の木である、 tree ver1 の末尾ノードが2つの子ノードを持っているせいで発生する。
  この問題を解決するために、Differential Jungle Tree では、過去の木に対する変更を禁止している。具体的には。末尾ノードは子を1つしか持つことができないようにした。そうすることで木の整合性を保証している。
 
 
%画像つくる  
\begin{figure}[ht]
    \begin{center}
        \includegraphics[width=70mm]{./pic/EditDifferencialTree.pdf}
    \end{center}
    \caption{木の整合性が崩れる例}
    \label{fig:EditDifferencialTree}
\end{figure}

\section{Red Black Jungle Tree の実装}
 Jungle は木に編集を加えた際、ルートから編集を行う位置までのノードをコピーする。その為、木の編集の手間は木の大きさにも依存している。バランスの取れた木構造を構築することで、編集の手間をO(log n)にすることは可能だが、Default Jungle Tree の場合、ユーザーがPath を用いて、バランスを取りながら木を構築する必要がある。しかし、ユーザーが全ての木構造の形を把握し、バランスの取れた木を構築するのは困難である。そこで、自動で木のバランスを取り、最適な形の木構造を構築する機能を持つ Red Black Jungle Tree を実装した。バランスは、木の生成時に特定の Balance Key を決定し、それを使って行う。木のバランスを取るアルゴリズムは、前述した非破壊 TreeMap と同じものを使用する。しかし、木の編集を加えた際、木がどのようにバランスを取るか予想するのは困難であるため、木構造自体がデータを表現していない場合に限る。また、自身の木構造が、Balance Key  を使った Index と同じ働きを持つため、木のCommit 時に別途 Index を構築する必要が無い、といったメリットもある。

\paragraph* {Red Black Jungle Tree の作成}
 Red Black Jungle Tree を作成するため、Jungle に新しいAPIを実装した。(表)

\begin{table}[htb]
  \begin{center}
  \caption{Jungleに新しく実装したAPI}
    \begin{tabular}{|p{3cm}|p{4cm}|} \hline
    \hline \shortstack{ createNewRedBlackTree\\ (StringtreeName, \\String balanceKey)}&  Jungleに新しくRed Black Jungle Treeを生成する。第一引数に木の名前、第2引数に木のバランスを取る時に使用する Balance Key を受け取る。木の名前が重複した場合、生成に失敗し null を返す。\\ 
    \hline
    \end{tabular}
   \label{table:Diffetential API}
  \end{center}
\end{table}

\paragraph* { NodePath の拡張}
 Red Black Jungle Tree は、ノードを追加・削除するたびに木のバランスが行われ、各ノードの Path が変わってしまう。その為、数字を使った NodePath では、編集を加える際、編集対象のノードの Path を毎回調べる必要がある。その問題を解決するために、NodePath を拡張した Red Black Tree Node Path を作成し、属性名 BalanceKey 属性値 value のペアでノードを指定できるようにした。 Red Black Jungle Node Path は、引数に String 型の BalanceKey と ByteBuffer 型の value を取る。
 %サンプル要りますでしょうか
  Red Black Tree Node Path で指定できる属性名は、木の生成時に宣言した属性名しか使用できない。これは、Red Black Jungle Tree が木の生成時に宣言した属性名でソートされているからである。

%\paragraph* { Red Black Jungle Tree の編集}
 %Red Black Jungle Tree Editor は、既存の Jungle Tree Editor とくらべてAPIの使い方が異なる。以下にDefault Jungle Tree と Red Black Jungle Tree Editor のAPIの使い方の違いを記述する。
%\paragraph* { Jungle Red Black Tree の検索}
%編集と検索をいれるか迷います。

%Code \ref{src: "src"フォルダの中のコードのファイル名}で、文章中にコードの指定ができる。 
%\lstinputlisting[label=src:ファイル名, caption=Enqueue]{./src/ファイル名.拡張子}


\section{分散環境でのJungleDBの書き出し実験方法の提案}

\section{まとめ}


%参考文献 
\nocite{*}
\bibliographystyle{ipsjunsrt}
\bibliography{sigos}

\end{document}