Mercurial > hg > Papers > 2017 > tatsuki-master
diff slide/slide.html @ 27:796c18a4aa0d
add slide
author | tatsuki |
---|---|
date | Sun, 12 Feb 2017 16:24:24 +0900 |
parents | |
children | 222d98af3372 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slide/slide.html Sun Feb 12 16:24:24 2017 +0900 @@ -0,0 +1,778 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="content-type" content="text/html;charset=utf-8"> +<title>修論予備審査Slide</title> + +<!-- +Notes on CSS media types used: + + 1) projection -> slideshow mode (display one slide at-a-time; hide all others) + 2) screen -> outline mode (display all slides-at-once on screen) +3) print -> print (and print preview) + + Note: toggle between projection/screen (that is, slideshow/outline) mode using t-key + + Questions, comments? + - send them along to the mailinglist/forum online @ http://groups.google.com/group/webslideshow + --> + + <!-- styles --> + <style media="screen,projection"> + + html, + body, + .presentation { margin: 0; padding: 0; } + + .slide { display: none; +position: absolute; +top: 0; left: 0; +margin: 0; +border: none; +padding: 2% 4% 0% 4%; /* css note: order is => top right bottom left */ + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +width: 100%; height: 100%; /* css note: lets use border-box; no need to add padding+border to get to 100% */ + overflow-x: hidden; overflow-y: auto; + z-index: 2; + } + +.slide.current { display: block; } /* only display current slide in projection mode */ + +.slide .stepcurrent { color: black; } +.slide .step { color: silver; } /* or hide next steps e.g. .step { visibility: hidden; } */ + +.slide { + /* + background-image: -webkit-linear-gradient(top, blue, aqua, blue, aqua); + background-image: -moz-linear-gradient(top, blue, aqua, blue, aqua); + */ +} +</style> + +<style media="screen"> +.slide { border-top: 1px solid #888; } +.slide:first-child { border: none; } +</style> + +<style media="print"> +.slide { page-break-inside: avoid; } +.slide h1 { page-break-after: avoid; } +.slide ul { page-break-inside: avoid; } +</style> + + +<!-- add js lib (jquery) --> +<script src="js/jquery-1.7.min.js"></script> + +<!-- S6 JS --> +<script src="js/jquery.slideshow.js"></script> +<script src="js/jquery.slideshow.counter.js"></script> +<script src="js/jquery.slideshow.controls.js"></script> +<script> +$(document).ready( function() { + Slideshow.init(); + + // Example 2: Start Off in Outline Mode + // Slideshow.init( { mode: 'outline' } ); + + // Example 3: Use Custom Transition + // Slideshow.transition = transitionScrollUp; + // Slideshow.init(); + + // Example 4: Start Off in Autoplay Mode with Custom Transition + // Slideshow.transition = transitionScrollUp; + // Slideshow.init( { mode: 'autoplay' } ); + } ); +</script> + +</head> +<body> +<div class="layout"> +<div id="header"></div> +<div id="footer"> +<div align="right"> +<img src="image/concurrency.png" width="200"> +</div> +</div> +</div> + +<div class="presentation"> + +<!-- add slides here; example --> +<div id="header"> + +<tr> +<td><div align="center"> +<h1><font color="#808db5">ソフトウェア内部で使用するのに適した木構造データベースJungle</font></h1> +<h2>琉球大学大学院 情報工学専攻 修士2年次 金川竜己</h2> +<p>Feb 13, 2017</p> +</div></td> +</tr> +</div> + +<div> +<h1>研究の背景と目的</h1> +<font size=5> +<p>プログラムからデータを分離して扱うデータベースには、プログラム中のデータ構造と表構造とのミスマッチという問題がある。</p> +<p>データベースのレコードをプログラム中のオブジェクトとして使えるOR Mapperや、データベース自体も、表に特化したKey Value Storeや、Jsonなどの不定形のデータ構造を格納するように機能拡張されてきている。</p> +<p>しかし、プログラム中のデータは複雑な構造をメモリ上に構築しており、これらの方法でもまだギャップがある。</p> +</font> +</div> + +<!-- +<div> +<h1>インピータンスミスマッチ</h1> +<font size=5> +<p>プログラム中のデータ構造とRDBの表構造には大きなギャップがある。これはインピーダンスミスマッチと呼ばれている。</p> +<p>例えばRPGゲーム中のユーザが持つアイテムという単純なものでも、RDBではユーザとアイテムの組をキーとする巨大な表として管理することになる。</p> +<p>プログラム中では、ユーザが持つアイテムリストという簡単な構造を持つが、データのネスト構造を許さない第一正規形を要求するRDBとは相容れない。</p> +</font> +</div> +--> + + +<div> +<h1>既存のDBが持つ問題点</h1> +<font size=5> +<p>MySQLやPosgreSQLなどは、Jsonなどの不定形のデータ構造を格納するように機能拡張されるようになってきた。</p> +<p>しかし、不定形の構造の変更をトランザクションとして、どのように処理するかはJsonの一括変更という形で処理されてしまっており、 +並列処理が中心となってきている今のアプリケーションには向いていない。</p> +<p>この拡張はRDBよりの拡張であり、 +並列処理を含むプログラミングからの要請とのミスマッチが残っている。</p> + +</font> +</div> + +<div> +<h1>既存のDBが持つ問題点</h1> +<font size=5> +<p>データベース自体も、表に特化したKey Value Storeや、Jsonなどの不定形のデータ構造を格納するように機能拡張されてきている。</p> +<p>その例としてCassandraや、mongoDBが挙げられる。</p> +<p>しかし、プログラム中のデータは複雑な構造をメモリ上に構築しており、これらの方法でもまだギャップがある。</p> +</font> +</div> + + +<div> +<h1>非破壊的木構造データベースJungle</h1> +<font size=5> +<p>当研究室ではこれらの問題を解決するために木構造Jungleデータベースを提案している。</p> +<p>Jungleは様々な構造のデータ(例えばXML/JSON/LIST)を木構造としてそのまま格納することが可能である。</p> +<p>Jungleではデータの変更を非破壊的、つまり元の木を保存しつつ、新しい木を構築する方法をとる。</p> +<p>これにより木を参照しながら処理するタスクと木を変更するタスクを並列に処理することができる。</p> +<p>プログラムは、この木を変更されないデータ構造として直接取り扱うことができる。</p> +<p>名前付きの複数の木をatomicに入れ替えるのがJungleの transactionとなる。</p> +</font> +</div> + + +<div> +<h1>Jungleの構造</h1> +<font size=5> +<p>木は複数のノードの集合でできており、その木の集合によりJungleが構成されている。</p> +<p>ノードは自身の子のリストと属性名と属性値の組でデータを持つ。これはデータベースのレコードに値する。</p> +<p>通常のレコードと異なり、ノードは自身の子供を持つ。</p> +<p>親から子への片方向の参照しか持たない。</p> +<embed src="../figures/multiComponent.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<h1>JungleのTransaction</h1> +<font size=5> +<p>データの変更は一度生成した木を上書きせず、ルートから変更を行うノードまでコピーを行い、新しく木構造を構築する。最後にルートをアトミックに入れ替えてコミットする。コミットが失敗した場合は最初からやり直す。</p> +<embed src="../figures/non_destructive_tree.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<h1>Jungleの木</h1> +<font size=5> +<p>Jungleは木を名前で生成、管理している。</p> + +<div style="padding: 10px; margin-bottom: 10px; border: 5px double #333333;"> +<pre><code class="language-Java"> +// Jungleに新しく木を生成する。木の名前が重複した場合、生成に失敗しnullを返す +JungleTree createNewTree(String treeName) + +// JungleからtreeNameと名前が一致するtreeを取得する。名前が一致するTreeがない場合取得は失敗しnullを返す +JungleTree getTreeByName(String treeName) +</code></pre> +</div> + +</font> +</div> + + +<div> +<h1>Jungleの木の編集</h1> +<font size=5> +<p>Jungleの木の編集はJungleTreeEditorクラスを用いて行われる。</p> + +<p>JungleTreeEditorクラスには編集を行うためのAPIが実装されている。</p> + +<p>また、ノードを指定して編集を行う際には、NodePathクラスを用いる。</p> + +<p>木の編集を行った後は、Commitを行い変更をPushする必要がある。</p> +</font> +</div> + + +<div> +<h1>NodePath</h1> +<font size=5> +<p>Jungleでは木のノードの位置をNodePathを使って表す。</p> +<p>ルートから対象のノードまでの経路を数字で指し示す。</p> +<p>ルートノードは例外として-1と表記される。</p> +<p>NodePathクラスを用いて[-1,1,2,3]を表している例を以下に貼る。</p> +<embed src="../figures/nodepath.pdf" width="800" height="500"/> +</font> +</div> + + + + +<div> +<h1>JungleTreeEditorのAPI</h1> +<font size=5> +<p>JungleTreeEditorが提供している木の編集APIを以下に記す。</p> +<div style="padding: 10px; margin-bottom: 10px; border: 5px double #333333;"> +<pre><code class="language-Java"> + +</code></pre> +</div> + +</font> +</div> + + + +<div> +<h1>Jungleの検索機能</h1> +<font size=5> +<p>Jungleの木への検索は、木の走査を行うTraverserクラス内に実装してある。</p> + +<p>属性名key 属性値valueの組を使用して検索を行う。</p> + +<p>以下に検索を行う関数findの定義を記述する。</p> + +<div style="padding: 10px; margin-bottom: 10px; border: 5px double #333333;"> +<pre><code class="language-Java">public Iterator<TreeNode> find(Query query, String key, String value); +</code></pre> +</div> + +<p>関数findは引数に、Query query、String key、String valueの3つの引数を取り、条件に一致したノードのIteratorを返す。</p> + +<p>第1引数には、探索の条件を記述する関数boolean comdition(TreeNode)を定義したInterface Queryを、第2、第3引数の、String key、String valueはIndexを用いた絞込みに使用する。</p> + + +</font> +</div> + +<div> +<h1>Jungleの問題点</h1> +<font size=5> +<p>これまでに記述したAPIにより、Jungleはデータの書き込み、読み込みを行える。</p> +<p>しかし、性能はあまり良いものではなかった。</p> +<p>特にIndexを用いた検索が明らかに遅く、検索の手間がO(n^2)となっていた。</p> +<p>本来ならIndexを使った場合の検索の手間はO(Log n)であるべきである。</p> +</font> +</div> + + +<div> +<h1>JungleのIndexが遅い原因</h1> +<font size=5> +<p>Jungle では、今まで Java 上で関数型プログラミングが行えるライブラリ、Functional Java の TreeMap を使用して、Index を実装していた。</p> +<p>しかし、Functional Java の TreeMap は、採用しているアルゴリズムが悪かった。</p> +<p>またコードの量も膨大であり、修正も困難だった。</p> +<p>そこで、自分で、同じ機能を持つ 非破壊 TreeMap を実装することにした。</p> +<p>TreeMap アルゴリズムは赤黒木を採用した。</p> +</font> +</div> + + +<div> +<font size=5> +<h1>Indexに非破壊TreeMapを採用している理由</h1> +<p>Jungleは過去の版の木を全て保持している。</p> +<p>過去の木に対する検索もサポートしている。</p> +<p>木の版毎にIndexを持っている必要がある</p> +<p>破壊的TreeMapでは、木に更新が入るたびに新しいIndexを作り直す必要がある。</p> +<p>Indexの更新の手間がO(n)になってしまう。</p> +<p>非破壊TreeMapの場合、一度作られたTreeMapに対して編集を行うと、編集後のTreeMapを返す。</p> +<p>その際、編集前のTreeMapのデータは破壊されることはない。</p> +<p>また、過去のIndexとデータを共有している</p> +<p>複数のversionのIndexがあっても、データの差分しかメモリは消費されない</p> +<p>メモリの使用量を抑えつつ複数のversionでIndexを保持できる</p> +</font> +</div> + + +<div> +<h1>赤黒木とは</h1> +<font size=5> +<p>赤黒木とは、二分探索木の一つで、以下の条件を満たした木のことである</p> +<ul> +<li>全てのノードは赤か黒の色を持つ</li> +<li>ルートノードの色は黒</li> +<li>全ての葉の色は黒</li> +<li>赤いノードの子の色は黒</li> +<li>全ての葉からルートまでの経路には同じ個数の黒いノードがある</li> +</ul> +<p>赤黒木は、上記の条件を満たしている限りデータの検索、削除、探索をO(Log n)で行える。</p> +</font> +</div> + +<div> +<h1>Jungleの問題点2</h1> +<font size=5> +<p>非破壊のTreeMapを実装したことにより、読み込みは極めて高速に行えるようになった。</p> +<p>しかし、書き込みに関してはまだ十分な速度が出ていない。</p> +<p>Jungleの木の編集時に特に問題になっているのは、主に次の三点である。</p> +<ul> +<li>Indexの更新が、毎回フルアップデートしているため更新の手間がO(n)となっている。</li> +<li>線形の木を更新する際、Jungleは全てのノードの複製を取ってしまうため、更新の手間がO(n)となってしまう</li> +<li>木のノード数が増えると、バランスが取れていない場合木の更新が重くなる。</li> +</ul> +<p>以降これらの問題について述べていく。</p> +</font> +</div> + +<div> +<h1>Indexの差分アップデート</h1> +<font size=5> +<p>JungleではIndexの更新を行う際、毎回新しいIndexを構築していた。</p> +<p>その為、毎回O(n)のIndexの更新が入っていた。</p> +<p>Indexの差分アップデートを実装することで、Indexの更新の手間をO(Log n)とする。</p> +</font> +</div> + +<div> +<h1>Indexの差分アップデートの実装</h1> +<font size=5> +<p>Jungleは木の編集を行う際、編集を行うノードからルートまでの経路のノードの複製を行う。</p> +<p>そのため、編集後の木には存在しない、複製前のノードがIndexに残ってしまう。</p> +<p>それらのノードをIndexから削除し、複製後のノードを登録する必要がある。</p> +<embed src="../figures/non_destructive_tree.pdf" width="800" height="500"/> +<p>この図だと、Indexの更新時にroot、2、5をIndexから削除する必要がある。</p> +<p>その後新しく作られたノードを登録することでIndexの更新は完了する</p> +</font> +</div> + +<div> +<h1>複製前のノードのdelete</h1> +<font size=5> +<p>複製前のノードをIndexから削除するためには、編集を行ったノードを覚えておく必要がある。</p> +<p>Editorの中に編集を加えたノードを格納するリストを定義した。</p> +<p>Indexのアップデート時にリストを使用する。</p> +</font> +</div> + + +<div> +<h1>複製前のノードのdelete</h1> +<font size=5> +<p>複製前のノードは以下の手順で行われる。</p> +<ol> +<li>編集を行ったノードのリストからノードを取得する。</li> +<li>取得したノードが、保持している値をIndexから削除する。 </li> +<li>自身と子供のペアを ParentIndex から削除する。</li> +<li>ParentIndexから自身の親を取得する。</li> +<li>2 - 4 をルートノードにたどり着くか、ParentIndex から親を取得できなくなるまで続ける。 </li> +<li>1 - 5 をリストからノードが無くなるまで続ける。</li> +</ol> +</font> +</div> + +<div> +<h1>編集前のノードのdeleteの例1</h1> +<font size=5> +<p>ノードD、Eを編集した後の、複製前のノードをIndexから削除する例を記述する。</p> +<p>黒のノードは編集後の木に存在しないノード。</p> +<p>赤のノードはIndexから削除が終了したノード。</p> +<p>その他のノードは緑とする。</p> +<br> +<p>編集前ノードのDelete前</p> +<embed src="../figures/indexUpdate.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<h1>編集前のノードのdeleteの例2</h1> +<font size=5> +<p>ノードDについての削除後</p> +<embed src="../figures/indexUpdate2.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<h1>編集前のノードのdeleteの例3</h1> +<font size=5> +<p>ノードEについての削除後</p> +<embed src="../figures/indexUpdate3.pdf" width="800" height="500"/> +<p>このようにIndexからのノードの削除は行われる</p> +</font> +</div> + + +<div> +<h1>ノードのIndexへの追加</h1> +<font size=5> +<p>Indexへのノードは以下の手順で行われる。</p> +<ol> +<li>木からルートノードを取得する。</li> +<li>取得したノードがIndexに登録されているかを調べる。</li> +<li>登録されている場合、そのノード以下のSubTreeは、全てIndexに登録されているので、次のノードに移動する。</li> +<li>登録されていなかった場合、自身が保持している値をIndexに登録する。</li> +<li>自身と子ノードを Parent Index に登録する。</li> +<li>自身の子ノードを取得したノードとして2に戻る。</li> +<li>全てのノードを登録したら終了する。</li> +</ol> +<p>ノードの登録は深さ優先探索と同じ順序で行っていく。</p> +</font> +</div> + +<div> +<h1>ノードのIndexへの追加例</h1> +<font size=5> +<p>ノードD、Eを編集した後の、複製前のノードをIndexから削除する例を記述する。</p> +<p>赤のノードはIndexに存在しないノード。</p> +<p>緑のノードはIndexに追加されているノード。</p> +<br> +<p>以下の図の場合、A、B,D、Eの順に登録され、Cで終了する。</p> +<embed src="../figures/indexUpdate3.pdf" width="800" height="500"/> + +</font> +</div> + + +<div> +<h1>線形の木の構築</h1> +<font size=5> +<p>Jungleは木の編集時、ルートから編集を行う位置までのノードの複製を行う。</p> +<p>そのため、木の編集の手間は木構造の形によって異なる。</p> +<p>特に線形の木の場合、全てのノードの複製を行うため変更の手間がO(n)となってしまう。</p> +<p>Jungleは線形の木をO(1)で変更するPushPopの機能を持つ。</p> +</font> +</div> + +<div> +<h1>PushPop</h1> +<font size=5> +<p>PushPopはルートノードの上に新しいルートを追加するAPIである。</p> +<p>しかし、PushPopで構築した木は逆順になってしまう。</p> +<p>そのため、正順の木を構築する際は使用できない。</p> +<embed src="../figures/PushPopDemerit.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<h1>Differential Jungle Tree</h1> +<font size=5> +<p>正順の木をO(1)で構築するために実装した。</p> +<p>Differential Jungle Treeは木のバージョン毎に自身の木の最後尾のノードを持つ。</p> +<embed src="../figures/findDifTree.pdf" width="800" height="500"/> +<p></p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの作成</h1> +<p>Differential Jungle Treeを作成するためにJungleに新しいAPIを実装した。</p> +<div style="padding: 10px; margin-bottom: 10px; border: 5px double #333333;"> +<pre><code class="language-Java"> JungleTree createNewDifferenceTree(String treeName); +</code></pre> +</div> +<p>上記のAPIは、treeNameで指定した名前のDifferential Jungle Treeを構築する。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの編集</h1> +<p>Differential Jungle Treeの木の編集は、Differential Jungle Tree Editorを用いて行う。</p> +<p>既存のDefault Jungle Treeは、木の複製を作った後編集を行う。</p> +<p>Differential Jungle Tree Editorは、自身がSub Treeを持っている。</p> +<p>Sub Tree に対して編集を行う。</p> +<p>Commit時に自身が保持している末尾ノードにSub TreeをAppendすることで木の編集を終了する。</p> +<p>また、Diffirential Jungle Treeの編集は、Editorが持つSub Treeへの編集しか行えないため、一度Commitした木に対して変更を加えることはできない。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの編集の例</h1> +<p>Differential Jungle Treeの編集例を以下の図に記す。</p> +<embed src="../figures/EditDifferencialTree.pdf" width="800" height="500"/> +<p></p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの検索</h1> +<p>Differential Jungle Treeは末尾ノードを使って現在の木構造を表現している。</p> +<p>過去の木に対してIndexを使わないで全探索を行った場合、既存の検索ではその版に存在しないはずのノードが取得できてしまう。</p> +<embed src="../figures/findDifTree.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの検索例</h1> +<p>以下の図の場合Tree Ver1を全探索すると、存在しないはずのノード3、4が取得できてしまう。</p> +<embed src="../figures/findDifTree.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Interface Traverserの実装</h1> +<p>この問題を解決するためにDifferential Interface Traverserを実装した。</p> +<p>これは、末尾ノード以下を検索対象から取り除く検索を持つ。</p> +<p>Indexを使った検索の場合、各版ごとに独立したIndexを持つため、Default Jungle Treeと同じ検索でも問題ない。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの整合性</h1> +<p>Default Jungle TreeへCommitは編集後の木のルートをAtomicに入れ替えることで行う。</p> +<p>しかしDifferential Jungle Treeは、ルートの入れ替えと、Editorが持つ木構造の末尾ノードへのAppendの2つのプロセスからなる。</p> +<p>ルートの入れ替えに関しては、Default Jungle Treeと同じように行う。</p> +<p>Editorが持っている木構造の末尾ノードへのAppendは、ルートの入れ替えに成功した場合のみ行う。</p> +<p>そうすることで、別Threadで行われているCommitと競合した際に、ルートを入れ替えたThreadと別ThreadがAppendを行い木の整合性が崩れることを回避している。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの整合性2</h1> +<p>Differential Jungle Treeでは、過去の版の木に対して変更を加えた際に木の整合性が崩れてしまう問題もある。</p> +<p>図の中の、過去の木であるTree ver1に対してノード5を追加してCommitした場合、新しい木Tree ver`2が生成される。</p> +<embed src="../figures/badDifTree3.pdf" width="800" height="500"/> + +</font> +</div> + +<div> +<font size=6> +<h1>Differential Jungle Treeの整合性3</h1> +<p>Tree ver`2に対してIndexを使わないで検索を行った場合、本来存在しないはずのノード3、4が検索対象に入ってしまう。</p> +<p>これは、Tree ver1の末尾ノードが2つ子を持っているせいで発生する。</p> +<p>この問題を解決するために、過去の木に対する変更は禁止した。</p> +<embed src="../figures/badDifTree2.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>Jungle上での巨大な木の扱い。</h1> +<p>Jungleは木の編集時、ルートから編集を行う位置までのノードの複製を行う。</p> +<p>そのため、木の編集の手間は木構造の大きさにも依存している。</p> +<p>バランスの取れた木構造を構築することで、編集の手間をO(Log n)にすることは可能ではある。</p> +<p>しかし、ユーザーが木の構造を把握しバランスを取るのは難しい。</p> +<p>そこで、自動で木のバランスを取り、最適な木構造を構築する機能を持つRed Black Jungle Treeを実装した。</p> +<p>Red Black Jungle Treeは、自動でバランスを取ってしまうため、木構造の形でデータを表現することはできない。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Red Black Jungle Treeの作成</h1> +<p>Red Black Jungle Treeを作成するためにJungleに新しいAPIを実装した。</p> +<div style="padding: 10px; margin-bottom: 10px; border: 5px double #333333;"> +<pre><code class="language-Java"> JungleTree createNewRedBlackTree(String treeName,String balanceKey); +</code></pre> +</div> +<p>上記のAPIは、treeNameで指定した名前のRed Black Jungle Treeを構築する。</p> +<p>また、第二引数のbalanceKeyを用いて木のバランスを取る。</p> +<p>第二引数のbalanceKeyを使用して、検索することでO(Log n)で検索を行うことができる。</p> +<p>なので、別途Indexを構築する必要はない。</p> +</font> +</div> + + +<div> +<font size=6> +<h1>NodePathの拡張</h1> +<p>Red Black Jungle Treeは、ノードを追加、削除するたびに木のバランスが行われるため、各ノードのPathが変わってしまう。</p> +<p>その為、編集を加える際に、編集対象のノードのPathを調べる必要がある。</p> +<p>その問題を解決するために、ノードを数値ではなく属性名と属性値の組でノードを指定できるようにした。</p> +<p>ノードの指定に使用する属性名は、Red Black Jungle Treeの第二引数で指定したbalanceKeyを使用する必要がある。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Red Black Jungle Treeの検索</h1> +<p>Red Black Jungle TreeはIndexを持たないため既存の検索は使用できない。</p> +<p>木の生成時に指定したbalanceKeyを使用して、O(Log n)で探索を行う検索を実装した。</p> +<p>また、balanceKeyを使用しない場合は、既存のDefault Jungle Treeと同じで全探索を行うのでO(n)となる。</p> +</font> +</div> + + + +<div> +<font size=6> +<h1>新たに追加した要素の評価</h1> +<p>Jungleに新しく追加した機能の性能測定を行う。</p> +<p>新しく実装したTreeMapとFunctionalJavaのTreeMap</p> +<p>IndexのFullアップデートと差分アップデート</p> +<p>Default Jungle TreeとDefferential Jungle Tree</p> +<p>Default Jungle Tree と Red Black Jungle Tree</p> +<p>最後に既存のDBであるPostgreSQLとMongoDBとJungleの比較を行う。</p> +</font> +</div> + + + +<div> +<font size=6> +<h1>TreeMapの測定</h1> +<p>比較対象には、 TreeMap 実装前に Jungle で使用していた Functional Java の TreeMap を使用する。</p> +<p> TreeMap に1000回の Get を行った際のグラフである。</p> +<!-- +<p>X 軸は Get を行う TreeMap のノード数。</p> +<p>Y 軸は Get にかかった時間を表す。</p> +--> +<embed src="../result/treemap/find.pdf" width="800" height="500"/> +</font> +</div> + + + +<div> +<font size=6> +<h1>TreeMapの測定の考察</h1> +<p>新たに実装したTreeMapの方が極めて高速な検索を行えている。</p> +<p>理由として、JungleのTreeMapは二分探索木の探索アルゴリズムで探索するのに対して、Functional Javaは検索対象のノードがルートになる木を再構築し、ルートを返すといったアルゴリズムのを採用しているからである</p> +<p>また、データのInsertは、ほぼ同じ速度、DeleteはJungleの方が極めて高速に行えていた。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Indexの差分アップデートの測定</h1> +<p>比較対象は、IndexのFullアップデートとする。</p> +<p>測定は木にノードを追加、Commitを1 セットの変更として行う。</p> +<!-- +<p>X 軸は、木に行った変更のセット数。</p> +<p>Y 軸は、木の構築にかかった時間を表す。</p> +--> +<embed src="../result/createIndex.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>Indexの差分アップデートの測定の考察</h1> +<p>IndexのFullアップデートに比べて差分Updateの方が高速に木の構築に成功している。</p> +<p>期待通りの性能が出たといえる。</p> +</font> +</div> + +<div> +<font size=6> +<h1>正順の線形木の構築時間の測定</h1> +<p>Differential Jungle Treeの性能測定を行う。</p> +<p>比較対象はDefault Jungle Treeを選択した。</p> +<p>また、木の構築時間を測るためにIndexを構築していない。</p> +<!-- +<p>X軸は構築した木のノード数。</p> +<p>Y 軸は構築にかかった時間を表す。</p> +--> +<embed src="../result/createListTree.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>正順の線形木の構築時間の考察</h1> +<p>Commit毎に全てのノードの複製を行うDefault Jungle Treeに比べて、木の複製を行わないDifferential Jungle Treeが早いのは当然だといえる。</p> +<p>期待通りの性能が出た。</p> +</font> +</div> + +<div> +<font size=6> +<h1>Red Black Jungle Tree の測定</h1> +<p>比較対象は、Default Jungle Treeを選択した。</p> +<embed src="../result/createRedBlackTreeAndDefaultTreeTime.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>Red Black Jungle Tree の測定の考察</h1> +<p>Red Black Jungle Treeは自身の木の形がIndexと同じ働きを持っている。</p> +<p>なのでIndexを木の編集時作る必要がない。</p> +<p>Commit のたびにIndexを作っているDefault Jungle Treeより早くなるのは当然だといえる。</p> +<p>期待通りの性能が出た。</p> +</font> +</div> + +<div> +<font size=6> +<h1>既存のDBとJungleの比較</h1> +<p>比較対象はMongoDBとPostgreSQLを選択した。</p> +<p>PostgreSQLはJson形式でデータを格納している。</p> +<p>データの検索速度を比較した。</p> +<embed src="../result/comparedb.pdf" width="800" height="500"/> +</font> +</div> + +<div> +<font size=6> +<h1>既存のDBとJungleの比較の考察</h1> +<p>MongoDBとPostgreSQLは、プログラム外にあるデータベースに通信を用いてアクセスしている。</p> +<p>Jungleは、メモリの中にデータを持ち通信を使わずデータにアクセスできる。</p> +<p>期待通りの性能が出た。</p> +</font> +</div> + + + +<div> +<font size=6> +<h1>まとめ</h1> +<p>Jungleの性能を向上させるために新たな要素を追加した。</p> +<ol> +<li>非破壊TreeMap</li> +<li>Indexの差分アップデート</li> +<li>Differential Jungle Tree</li> +<li>Red Black Jungle Tree</li> +</ol> +<p>実装後の測定では、全てが既存の木と比べて高速に動いていた。</p> +<p>また、Jungleは既存のDBと比較しても、極めて高速な検索が行えることがわかった。</p> +</font> +</div> + + +<div> +<font size=6> +<h1>今後の課題</h1> +<h2>木の設計手法の確立</h2> +<p>JungleはRDB と異なり格納するデータの自由度は大きい。</p> +<p>どのようなデータ構造も設計を行わずに格納することが可能である。</p> +<p>十分なパフォーマンスを出すためには、データを最適化する必要がある。</p> +<p>最適な木構造はアプリケーションによって違うため、Jungle の設計手法を確立させる必要がある。</p> +</font> +</div> + + + +</div> + + + +</div> + +</div> <!-- presentation --> +</body> +</html>