7/21の日記では,ページの階層構造をインデックス化することで,ページ表示時の処理を軽量化しようと考えたわけだが,実際にそれに着手しはじめた. 1.インデックスの論理構造カモランドで使っているプラグインを調べたところ,以下の情報を使っていることが判った.
そのため,これらの情報をインデックスとして持つことにする.
2.インデックスの物理構造物理的にどうやって持たせるか?だが,性能を考えるとメモリに持つのがよい.ただ,上記の(A)の想定だとデータ構造が入れ子構造(配列のハッシュ?)になるので,それが使えるかどうかも考える必要がある.具体的には,以下のような構造のハッシュが要るのだと思う.
IPC::SysV共有メモリ使ったことは無いが,ここらへんを見ると, あまり凝ったデータを持てそうな気がしないので却下.
RAMディスク上のファイルperltieを使ってハッシュをファイルにtieすれば,プログラム上はハッシュのままで扱えるので良さそうに思ったが, ここらへんを見ると,(ハッシュのハッシュのような)複数レベルのデータ構造をdbmファイルにtieすることは 簡単にはできません。 それで結局,カモランドの階層構造インデックス専用に,リストのハッシュを使えるようなperltieモジュールを作ることにした. このモジュールを使って,リストのハッシュをRAMディスク上のファイルに関連づけて保持する.
3.モジュールの実装以下のプログラムになります.基本はYukiWikiDB.pmを拝借しています.それにリストのハッシュ保持機能を追加しただけです.これを使って,RAMディスク上にカモランドのページの階層構造インデックスを保持できるようになったので, 今後はプラグインを順次このインデックスに対応させてゆけば良かろう. ArrayHashDB.pm package ArrayHashDB; use strict; # [使用例] # # (1) 書き込み # use ArrayHashDB; # tie(%db, "ArrayHashDB", "."); # $db{'カモランド'} = [qw(自宅サーバの構築 風景写真集 OracleMaster)]; # untie(%db); # # (2) 読み込み # use ArrayHashDB; # tie(%db, "ArrayHashDB", "."); # my(@v) = @{$db{'カモランド'}}; # foreach (@v) { # print "$_\n"; # } # untie(%db); # # Constructor sub new { return shift->TIEHASH(@_); } # tying # sub TIEHASH { my ($class, $db_directory) = @_; my $self = { dir => $db_directory, keys => [], }; if (not -d $self->{dir}) { if (!mkdir($self->{dir}, 0777)) { die "mkdir(" . $self->{dir} . ") fail"; } } return bless($self, $class); } # Store # $value: (reference of Array) # sub STORE { my ($self, $key, $value) = @_; my $filename = &make_filename($self, $key); my $data = join("\n", @$value); open(FILE, "+< $filename") or open(FILE, "> $filename") or die "Open $filename failed: $!\n"; flock(FILE, 2) or die "Exclusive lock failed: $!\n"; truncate(FILE, 0); print FILE $data; close(FILE); return $value; } # Fetch # return: (reference of Array) # sub FETCH { my ($self, $key) = @_; my $filename = &make_filename($self, $key); open(FILE, "$filename") or return(undef); flock(FILE, 1) or die "Share lock failed: $!\n"; local $/; # これがないと、1行しか読めない my $value = <FILE>; close(FILE); return [split(/\n/, $value)]; } # Exists # sub EXISTS { my ($self, $key) = @_; my $filename = &make_filename($self, $key); return -e($filename); } # Delete # sub DELETE { my ($self, $key) = @_; my $filename = &make_filename($self, $key); unlink $filename; # return delete $self->{$key}; } # データ格納ファイル名の生成 sub make_filename { my ($self, $key) = @_; my $enkey = uc(unpack("H*", $key)); return $self->{dir} . "/$enkey.txt"; }
モジュールの制限事項
|