IMAP の index ファイル ---------------------- どんなメール形式でも、サポートしなくてはならなく、少なくとも maildir と mbox 形式で、それを実行されることができます。 ファイル中のデータは、その環境でのバイトオーダーとタイプサイズを使用して、保 存されます。その情報は、インデックスファイルの "compatibility" フィールドに 保存されます。互換性のない index ファイルの対処は試みず、上書きされるだけで す。 index はヘッダーの "indexid" フィールドによってお互いに結び付けられています。 もし、それが一致しないときは、ファイルは破壊することになり、作り直されます。 メインのファイル ---------------- .imap.index: 修正されたサイズデータ これはメインの index ファイルです。スキャンをとても早く処理するために、でき るだけ小さくされます。 index は通常、求められている範囲の最初のレコードのポインタを得るため、アクセ スされます。その後、それは前にジャンプすることによって、アクセスされます。ス キップされたレコード(UID フィールドが 0)は、削除されます。 ヘッダの first_hole_position と first_hole_size は、インデックスファイルの最 初の削除されたブロックを指定します。もし、削除されたブロックの前のシーケンス ナンバーでメッセージをアクセスしたいならば、単純な配列検索によって行うことが できます。 ファイルの INDEX_COMPRESS_PERCENTAGE が削除されたスペースから構成されている とき(デフォルトは50%)、削除されたブロックは、圧縮されます。indexer のプロセ スは、余分な時間があるとき、シーケンス検索を早くしておくために、ファイルの圧 縮をしようとします。 ヘッダの cache_fields のフィールドは、新しいメッセージを index するときに、 index に保存しなければならないフィールドのビットマスクを含んでいます。それ は、いつでも変更され、古いメッセージは、変更を反映をするために更新を(すぐに は)しません。 データファイル -------------- .imap.index.data: 可変長のデータ メッセージの重要ではないフィールドを含みます。それぞれのメッセージは、修正さ れたサイズの "data header" とゼロかさらなる可変の幅のフィールドがあります。 それは、フィールドを追加や削除や編集することは可能ですが、もし割り当てられた スペースを超えた場合は、全てのデータブロックはファイルの終わりにコピーされま す。 削除されたスペースの総量は、記憶されており、例えば、ファイルの中ほどにある空 のブロックは再利用されません。ファイルの COMPRESS_PERCENTAGE が削除されたス ペースから構成されているとき(デフォルトは20%)、削除されたブロックは、圧縮さ れます。 このファイルは、実際には単なるダミーのデータベースであり、多分、将来的により 頭の良い)何か(Berkeley DB?)に置き換えられます。 現在、それはフィールドを挿入したり更新したりする必要がそれほどないため、 十分に良いのですが、しかし、 ANNOTATE 拡張はより良いものを望みます。 ANNOTATE は固定記憶装置を要求とするが、その index は本当は ... ではありませ ん。 ひとつの素晴らしいすべき考えは、単純に圧縮することです。メールボックスには多 くの同じメールアドレスとサブジェクトを含んでいますので、それを1つのインスタ ンスで単純に保存することができます。 tree ファイル ------------- .imap.index.tree:UID とシーケンス検索 これは tree ファイルの中の均衡二分木で、メインの index ファイルでメッセージ レコードの場所を見つけるために使われます。すべきこと:B+tree もしくはそれに 類似したものを使うべきことです。 ログファイルの修正 ------------------ .imap.index.log:外部の変更ログ 同じメールボックスにアクセスする2つの IMAP サーバ間でのやり取りは、通常あり ません。もし変更が起きた場合は、両方とも何が変更されたか見るために、メール ボックスへ行き、そして、そのことをクライアントに通知しなければなりません。 Dovecot は index ファイルに行われるログの変更を、ログファイルに変更します; 現在のメッセージフラグが変更か削除をします。そして、 Dovecot のプロセスの1 つは、メールボックスをスキャンしなければならず、他のプロセスは、ログファイル のどんな変更が起きたかについて単純にチェックします。 (例えば、メールを削除している他の MUA に)Dovecot が通知する全ての外部の変更 は、ログファイルにも保存されます。それは、クライアントがそれから通知される準 備ができているとき、そこから素早く見つけることができます。 メッセージシーケンスの処理は、 IMAP ではちょっとやっかいでもあります。クライ アンは、ト削除されたメッセージをすぐに知らせることはできないので、それぞれの クライアントは、少し異なったシーケンスを持つことができます。これを解決する最 も簡単な方法は、メッセージ又はメッセージ UID へのポインタを含むそれぞれのク ライアントに単純に seq_array[] を割り当てることです。これは多分、他の全ての IMAP サーバがそれを実行している方法です。 Dovecot はそのような配列を割り当てず、 index シーケンスとクライアントシーケ ンスとの間で何が異なっているのかを、ログファイルから単純に探します。それは、 ほとんどありません。これは実行するには少しトリッキーですが、今のところうまく 動作しているようです。 メールボックスにアクセスする Dovecot が1つのみの場合は、ログファイルに書く 必要はありません。このような場合に見つけるには、 fcntl() ロックのトリックを 使います。それぞれの Dovecot のプロセスは、共有モードでログの更新をロックす るので、もし1つだったとき、チェックすることは、それだけをロックしようとする のと同じくらい単純です。メインの index ファイルのみが、本当のロックに使われ るので、それは安全です。 外部の変更 ---------- (Maildir 形式のみ) 外部の変更は、 index ファイルのタイムスタンプが maildir のタイムスタンプと異 なったときに、チェックされます。 index ファイルを修正したとき、そのタイムス タンプは、いつ既知の同期した状態の最後かわかるように maildir のディレクトリ のタイムスタンプを設定しなければなりません。 ちょうどディレクトリの同期をした後に(もしくは、その最中に)、新しいメールが来 る可能性がまだありますが、それは、遅い処理である全ての時間を通してディレクト リをスキャンすることなしに、修正するのは少し難しいです。 幸運なことに、必ずわかる /new ディレクトリに新しいメールが来ますので、これは たいした問題ではありません。それは cur/ ディレクトリのみであって、もし他の誰 かがそれを壊したならば、必ずしも同期しないかもしれません。 ロック ------ ファイルのロックは fcntl() 関数を使って行われるので、現在、それをサポートし ていない NFS サーバは、サポートしていません。もしメールボックスが NFS 経由で アクセスされたとしても、 index はローカルのディスクに保存することは、多分必 要ないでしょう。