スレッドについて ○ Mail::Message::DB::_analyze_thread() スレッドの依存関係を調べる処理は _thread_analyze() が真髄の一つです。 この関数は HASH_REF(ref_key_list) doubly linked list HASH_REF(prev_key) HASH_REF(next_key) を更新しています。prev_key と next_key は最も参照関係の近い記事同士の 相互リンクを表しています。 さて、HASH_REF(ref_key_list) は、次のように更新されます。 ref_key_list に自分の ID を設定する( { id => id } )。 for $message_id (In-Reply-To と References にふくまれるID) { inv_message_id hash $message_id から参照されている ID を割出す ref_key_list->{ 参照されているID } に現記事の ID を追加 } たとえば、記事101を処理しているとし、記事101が100へのフォローだとしま しょう。この場合、next_key は { 100 => 101 } であり、prev_key は { 101 => 100 } となります。 さらに、101は90と91も参照せよと指示しているとします。また、90がスレッ ドの先頭で、91は90へのフォローだとしましょう。この場合、初期状態は次の ようになっています。 ref_key_list = { 90 => 91, }; 101の処理は次のようなループです。 for $message_id (100のmid, 90のmid, 91のmid) { $inv_message_id{ 100のmid } => 100 ref_key_list へ追加 } 結果として ref_key_list = { 100 => 101, 90 => "91 101", 91 => 101, }; 次に、記事102が101へのフォローなら、ref_key_list は次のようになるでしょ う。 ref_key_list = { 101 => 102, 100 => "101 102", 90 => "91 101 102", 91 => "101 102", }; なお、以上のような処理のため、 for $message_id (In-Reply-To と References にふくまれるID) { の処理の順番はどうでもいいはずです。 ○ Mail::Message::ToTHML::_print_thread() これが実際にスレッドの依存関係を HTML 化する関数です。 概念的には _print_thread() { for (ref_key_list id のリスト) { if (リストの中身が複数) { # あとで使うためにキャッシュしておく $self->{ _thread_list }->{ $id } = $buf; } print_ul() print_li() _print_thread() (recursive call) } print_ul_end() # recursive の回数だけ を出力する } [TODO] $self->{ _thread_list } はオンメモリだけど、 次回の処理のために db に書いておくべきじゃないのか?