データベース関連モジュール
概要もしくは理想像
MLドライバはメールのさまざまな要素をデータとして保存する必要がありま
す。しかしながら、同じ要素でも、永続的に持つべき場合と、一定時間経過後
に捨てて良い扱いの場合とがあります。
前者の例はスレッドのデータです。一方、後者の例はフィルタシステムの持っ
ている message-id cache などです。スレッドデータベースも同じく
message-id のデータを持っていますし、記事の分については重複しています。
ですが、2つの有効期間は異なるため別々に取り扱う必要があります。
とはいえ実際問題スレッド関係とそれ以外に集約できそうなので、
各モジュールの理想的な関係は次のようになるのでしょう。
モジュールA ---|ア|----- スレッド DB
モジュールB ---|ダ|
モジュールC ---|プ|
モジュールD ---|タ|----- キャッシュ (有効期限つき)
このスレッド DB は
Mail::Message::DB
のようなものとし、各種アダプタ層ががんばってほしい。
また、キャッシュの方だが、現在では Tie::JournaledDir もしくは
File::CacheDir かのいづれかが使われることとなる。
永続的なデータの保持
永続的にデータを保持する方法はいくつかあります。いい加減なものから大真
面目なものまでいろいろです。大真面目に考えると、LRU などの機能を持った
モジュールを利用して作るのかもしれませんが、やや大げさで、いまひとつしっ
くりこない気がします。つまり、そこまで真面目に virtual memory のような
実装をしなくてもよいのでは?という気がします。それに、もし切実に必要な
ら、なんらかの
DBMS
DBMS = DataBase Management System
を使うべきでしょう。
そういったわけで FML では、expire の仕方に応じて2つのデータ保持クラス
を用意しています。それは「サイズを気にせず、時間を区切って expire する
のか?」もしくは「使用する領域のサイズをある程度気にするか?」の2種類
です。
現在では
Tie::JournaledFile クラス
を利用した
Tie::JournaledDir クラス
もあるので、
将来
Tie::JournaledDir もしくは File::CacheDir かのいづれかは
不必要になるかも知れません。
また、インターフェイスの違いから適宜使い分けるのかもしれません。
2002/08:
File::CacheDir は改名し、なくす方向で考えています。
そもそも File::CacheDir は
FML/Process/Kernel.pm
と
FML/Filter/TrafficMonitor.pm
でしか使ってません。
しかも、
TrafficMonitor.pm は事実上未完成なので、まだ変更が可能です。
実際 FML::Process::Kernel の var/mail/ でしか使っていないので、
File::CacheDir を使わないようにすることが可能でしょう。
Tie::JournaledFile クラス
これは、一つのファイルに append していくタイプです。
この機能は
Tie::JournaledFile
クラスが提供します。
このクラスは、データを追加もするし参照もしたい場合に用いられますが、
追加のオペレーションしか行なえません。
つまり LFS (Log Structured File System) のような振舞いです。
参照する際は最後に追加したデータが取り出されます。
つまり、値は追加された値を last match で取り出しています。
逆に、必要な場合には、過去のログを追跡していくことができます。
このクラスは、サイズを度外視して一定期間のあいだ記録しておきたいデータ
に対して使います。例えば、登録時の confirmation のキャッシュや
message-id キャッシュです。これらは expire を時間で制御したいからです。
このクラスは引数でファイル名を与えることになっているので、ファイル名に
日付付のファイルを選ぶと良いでしょう。
なお、普通の tie() とは違う
key => [
ろぐ1 (どっかのふぁいるのどっかの行),
ろぐ2 (どっかのふぁいるのどっかの行),
ろぐ3 (どっかのふぁいるのどっかの行),
]
型のデータとりだしをしたい場合があります。
この形のデータ取り出しは
get_all_values_as_hash_ref()
メソッドを使えば可能です。
なお検索時の挙動の
first match と last match は切替えることができます。
どちらの戦略で探すのか、
クラスオブジェクトを生成する際に明示的に指定することが推奨されます。
デフォルトは first match です。
File::CacheDir クラス
この
File::CacheDir
クラスは、主にサイズに上限を設けたいタイプのデータを蓄える場合に用
います。expire の時間については気にしません。
サイズで有無を言わさず切ってしまいます。
デバッグ等に用いるデータはこれで十分と考えています。
普段は使わないデバッグのために、サイズを食われるのも嫌ですから。
このクラスは、あるディレクトリ(例: db/)の有限の複数のファイル郡の中に
データを蓄えます。
例えば db/ に 1 〜 100 の名前のファイルがつくられ、
順番に使われてきます。
これらのファイルはぐるぐる回って使われ、上書きされます。
旧 RingBuffer は File::CacheDir に統合されました。
モジュールの使い分け
う〜ん、困りましたね…
元々はサイズの上限を重視する場合が
リングバッファ、つまり File::CacheDir でした。
逆に、
時間方向の expire を重視する場合は Tie::Journaled* を使うつもりでした。
でも時間方向の File::CacheDir はそれと一緒じゃん;)