WebStorageを用いてツリー構造を持つデータを実装する

 WebStorageでは、Hash型のデータ構造しかサポートしていないが、多くのアプリケーションのデータ構造というのはツリー構造であり、ここではツリー構造の実装の仕方を解説する。

 なお、WebStorageの関連技術として、ディレクトリ-ファイル形式をサポートするものもあるが、ブラウザにより対応状況が大きく異なる上に、標準規格から外れるため、本ブログでは対象としない。

 簡単な実装方法として、要素名に「親要素名/子要素名/孫要素名」というようにパス構造をつける方法が挙げられる。以下にその例を示す。ただし、変数storageはStorageクラスの派生クラスとする。

storage.set('/home/test/case1.txt','data1');
storage.set('/home/test/case2.txt','data2');
storage.set('/home/test/case3.txt','data3');

この方法だと、ある要素の子要素を見つける際に、localStorage内の全要素を検索しないといけなくなるため、要素数が増大していくと要素探索時間がどんどん長くなる。つまり、スケーラビリティが失われるという問題があるため、大規模なアプリケーションを構築する際には推奨できない。

 より現実的なアプローチでツリー構造を実現する方法で簡単なのは変数をJSON形式に変換してLocalStorageに保存する方法である。下記にその例を示す。

var cluster={
	'D':{ // 'D' means sub directories
		'test':{
			'F':{ // 'F' means sub files
				"case1.txt":"data1",
				"case2.txt":"data2",
				"case3.txt":"data3"
			}
		}
	}
};
storage.set('home',Object.toJSON(cluster));

 この方法にも弱点がある。例えば、データ量の多いツリーをJSON形式にエンコードした場合、データサイズが大きくなりデコードに時間がかかる。巨大なアプリケーションでは、保存したデータの一部分のみを使うというケースの方が多いため、関連性の高いデータ群をクラスター化して、各クラスターをJSON形式に変換するアプローチのほうがスケーラビリティに優れたアプローチだといえよう。

 ここでは、クラスター定義のスキーマの例として、TeaOSで採用しているやり方を説明する。まず、下記に実装例を示す。

var cluster2=Object.toJSON({'D':{},'F':{}});
var root={ // root cluster
	'D':{ // sub directories
		'D1':{'t':'lD', 'D':{}, 'F':{}},
		'D2':{'t':'lC', 'cluster':storage.allocate('lc://', cluster2)}
	},
	'F':{ // sub files
		'1.txt':{'t':'if', 'C':'file context1'},
		'2.txt':{'t':'if', 'C':'file context2'}
	}
};
storage.set('@ftree',Object.toJSON(root));

 ルートクラスターは要素名’@ftree’に保存する。なお、クラスターには、ディレクトリ定義のハッシュテーブル’D’とファイル定義のハッシュテーブル’F’が定義されている。各ディレクトリの’t’属性にはクラスター型かディレクトリ型かを特定する型情報をを指定する。’t’属性が’lD’の場合は、ディレクトリ型であり、親ディレクトリと同じクラスターに保存される。’t’属性が’lC’の場合は、クラスター型であり、親ディレクトリと異なるクラスターに保存される。その場合、保存されている場所(要素名)は’cluster’属性に設定されている。簡単に言えば、’t’属性に’lC’を指定することで、自由に別クラスターを定義することができ、関連性の低いデータを別クラスターにすることを可能にしている。ちなみに、’lD’とはlocal directoryの略で、’lC’とはlocal clusterの略であるが、例えば、’sC'(server cluster)というように新たな’t’属性を定義することで、より柔軟なデータ構造が実現できる。このことについては次の記事で説明しよう。

 なお、TeaOSでは、このようなデータアクセスを容易にするための手段として様々なファイルアクセスAPIを用意しているが、下記はその例である。

FSys.mkdir('/D1');
FSys.mkdir('/D2',{'cluster':true});
FSys.touch(['/1.txt','/2.txt']);

なお、大規模なアプリケーションを構築する際には、今回解説した保存の他に、デコードしたデータをキャッシュしたり、より複雑なデータ構造をサポートしたり、暗号化したりなど様々な機能をサポートすることも必要になるが、TeaOSのファイルシステムはそのような処理を全てユーザから隠蔽している。

カテゴリー: html5_storage   タグ: , , , ,   この投稿のパーマリンク

コメントを残す