データベース関連モジュール 概要もしくは理想像 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 で取り出しています。 原理上 last match 以上の情報抽出も可能です。 過去のログを追跡していくことで、全データ一覧の生成ができます。 また、 last match を first 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 の名前のファイルがつくられ、 順番に使われてきます。 これらのファイルはぐるぐる回って(1 2 3 4 ...)使われ、 一周してしまう(100 を超えると)と、元に戻って上書き(1 2 3 4 ...)されます。 旧 RingBuffer は FML::Cache::Ring に統合されました。 また、FML::Cache::Ring は File::CacheDir から作られました。