データベース関連モジュール 概要もしくは理想像 MLドライバはメールのさまざまな要素をデータとして保存する必要がありま す。しかしながら、同じ要素でも、永続的に持つべき場合と、一定時間経過後 に捨てて良い扱いの場合とがあります。 前者の例はスレッドのデータです。一方、後者の例はフィルタシステムの持っ ている message-id cache などです。スレッドデータベースも同じく message-id のデータを持っていますし、記事の分については重複しています。 ですが、2つの有効期間は異なるため別々に取り扱う必要があります。 とはいえ実際問題スレッド関係とそれ以外に集約できそうなので、 各モジュールの理想的な関係は次のようになるのでしょう。 モジュールA ---|ア|----- スレッド DB モジュールB ---|ダ| モジュールC ---|プ| モジュールD ---|タ|----- キャッシュ (有効期限つき) このスレッド DB は Mail::Message::DB のようなものとし、各種アダプタ層が頑張って欲しい。 また、キャッシュの方ですが、現在では Tie::JournaledDir もしくは FML::Cache::Ring のいづれかが使われることとなっています。 なお、メンバーリストなどの永続性の必要なデータに対するデータベースはき ちんと DBMS (データベース管理システム)を使うべきです。ここで述べている データベースは fml8 が動作する上で内部的に使っているデータベースです。 永続的なデータの保持 永続的にデータを保持する方法はいくつかあります。いい加減なものから大真 面目なものまでいろいろです。大真面目に考えると、LRU などの機能を持った モジュールを利用して作るのかもしれませんが、やや大げさで、いまひとつしっ くりこない気がします。つまり、そこまで真面目に virtual memory のような 実装をしなくてもよいのでは?という気がします。それに、もし切実に必要な ら、なんらかの DBMS DBMS = DataBase Management System を使うべきでしょう。 ここでは fml8 内部で使っているモジュールの話をします。 &fml8; では、データの expire の仕方に応じて2つのデータ保持クラスを用 意しています。それは「サイズを気にせず、時間を区切って expire するのか?」 もしくは「使用する領域のサイズをある程度気にするか?」の2種類です。 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 は切替えることができます。 どちらの戦略で探すのか、クラスオブジェクトを生成する際に明示的に指定す ることが推奨されます。デフォルトは last match です(最後に書き込んだデー タが返される振舞いが自然です)。 FML::Cache::Ring クラス この FML::Cache::Ring クラスは、主にサイズに上限を設けたいタイプのデータを蓄える場合に用 います。expire の時間については気にしません。 サイズで有無を言わさず切ってしまいます。 デバッグ等に用いるデータはこれで十分と考えます。 普段は使わないデバッグのために、サイズを食われるのも嫌ですから。 このクラスは、あるディレクトリ(例: db/)の有限の複数のファイル群の中に データを蓄えます。 例えば db/ に 1 〜 100 の名前のファイルがつくられ、 順番に使われてきます。 これらのファイルはぐるぐる回って使われ、上書きされます。 旧 RingBuffer は FML::Cache::Ring に統合されました。 また、FML::Cache::Ring は File::CacheDir から作られました。