Linux Conference 2000: 全文検索システム Namazu 2.0

最終更新日: 2000-04-28 (公開日: 2000-04-28)

高林哲, 野首貴嗣


題目

Namazu の開発に学ぶプログラミングの教訓

高林哲が担当します。

改造とライブラリ化

野首貴嗣が担当します。


Namazu に学ぶプログラミングの教訓

高林哲

Namazu とは

Namazu は手軽に使えることを第一に目指した日本語全文検索シス テムです。CGI として動作させることにより小中規模の WWW 全文 検索システムを構築することができるほか、コマンドラインや Emacs上から利用するといった個人用途にも使えます。

Namazu は GNU General Public License version 2 に基づいたフ リーソフトウェアです。Namazu の最新情報は <http://www.namazu.org/> から入手できます。

Namazu の特徴

歴史

version 0.1.0 の開発

1996年6月30日から開発に着手。7月25日に完成。

ソースコードの行数

    % wc -l *.c *.pl
       1245 srnmz.c
        718 mknmz.pl
       1963 total

version 2.0 の開発

ソースコードの行数

    % wc -l **/*.c **/*.pl{,.in} scripts/*.in
    203 intl/bindtextdom.c         172 src/namazu-cgi.c        
    262 intl/cat-compat.c          336 src/namazu-cmd.c        
    624 intl/dcgettext.c           185 src/namazu.c            
     59 intl/dgettext.c            957 src/output.c            
    188 intl/explodename.c         757 src/rcfile.c            
    216 intl/finddomain.c          286 src/result.c            
     70 intl/gettext.c             105 src/usage.c             
     76 intl/intl-compat.c          76 filter/bzip2.pl         
    411 intl/l10nflist.c            76 filter/compress.pl      
    222 intl/loadmsgcat.c          108 filter/gfilter.pl       
    424 intl/localealias.c         119 filter/gzip.pl          
    108 intl/textdomain.c          298 filter/hnf.pl           
    504 lib/alloca.c               353 filter/html.pl          
     41 lib/easy-vsnprintf.c        92 filter/ichitaro456.pl   
   1050 lib/getopt.c               297 filter/mailnews.pl      
    187 lib/getopt1.c              136 filter/man.pl           
    381 lib/memcmp.c               122 filter/mhonarc.pl       
     28 lib/memmove.c               97 filter/msword.pl        
     29 lib/memset.c               218 filter/oleexcel.pl      
     77 lib/strcasecmp.c           250 filter/olemsword.pl     
     52 lib/strcspn.c              192 filter/olepowerpoint.pl 
     71 lib/strerror.c              92 filter/pdf.pl           
     80 lib/strncasecmp.c          114 filter/rfc.pl           
     44 lib/strstr.c               106 filter/tex.pl           
    157 lib/vsnprintf.c            127 pl/codeconv.pl          
    114 nmz/alias.c                204 pl/conf.pl              
    474 nmz/codeconv.c             481 pl/nmzidx.pl            
    213 nmz/field.c                171 pl/seed.pl              
    632 nmz/hlist.c                112 pl/usage.pl             
    183 nmz/i18n.c                 226 pl/util.pl              
    263 nmz/idxname.c              146 pl/var.pl               
     61 nmz/l10n-ja.c               98 pl/wakati.pl            
    181 nmz/libnamazu.c            204 pl/conf.pl.in           
    225 nmz/parser.c               117 pl/gettext.pl.in        
    207 nmz/query.c                146 pl/var.pl.in            
    170 nmz/re.c                   321 scripts/Makefile.in     
   4287 nmz/regex.c                137 scripts/bnamazu.in      
    235 nmz/replace.c              115 scripts/gcnmz.in        
   1113 nmz/search.c                21 scripts/gtnmz.in        
    146 nmz/seed.c                 159 scripts/kwnmz.in        
    542 nmz/util.c                 177 scripts/mailutime.in    
     55 nmz/var.c                 2228 scripts/mknmz.in        
    190 nmz/wakati.c                62 scripts/nmzgrep.in      
    274 po/cat-id-tbl.c             36 scripts/rfnmz.in        
    520 src/cgi.c                  106 scripts/vfnmz.in        
    464 src/form.c               27051 total                   

教訓

Namazu の開発では未熟なプログラマが陥るありがちな失敗をみご とに再現しています。自省の意味を込めて失敗から学んだ教訓をま とめます。

People learn from their failures. Seldom do they learn anything from success. -- Harold Geneen
人は失敗から学ぶ。成功から学ぶことはめったにない。

楽しい言葉

高林はプログラミング関連の警句を集めるのが趣味です。特に気に 入っているものを紹介します。

楽しい本

高林が特に好きな本を 2冊を紹介します。

Programming Pearls Second Edition
by Jon Bentley
Addison Wesley
$24.95
239ペイジ
Bell研究所の Jon Bentley 氏によるプログラミングに関するエッセ イ集。紹介されているプログラムはどれも巧妙で楽しいものばかり です。単にテクニックを紹介するのではなく、いかにして問題を解 くかに重点が置かれています。練習問題も楽しく、じっくり味わっ て読みたい本です。特にアルゴリズムに興味を持っている人はより 楽しく読めると思います。この本ほどプログラミングの楽しさを見 事に書き記した本を他に知りません。

プログラマのうちあけ話 (原書の More Programming Pearls は入手困難)
by Jon Bentley
近代科学社
3,000円
256ペイジ
Programming Pearls の続編。こちらはソフトウェア工学よりの内 容です。プロファイラ、テストとデバッグ、データの管理、概算の 手法、文書の設計、といった話題を扱っています。6章では計算機 科学に関する警句が集められています。実際にあったおもしろいエ ピソードが多数、紹介されている点もいいです (座っていればログ インできるが、立っているとログインできない。なぜだかわかりま す?)。楽しくてためになる本です。

その他の本の紹介は <http://cl.aist-nara.ac.jp/~satoru-t/programming/c.html> にまとめてあります。

今後の予定

まとめ


改造とライブラリ化

野首貴嗣

背景

現在では、非常に多くのフリーソフトウェアが流通しています。 しかも、その数や質は日を追うごとにより多く、高度になってきています。

このように多彩なフリーソフトウェアに囲まれている現在、 多くの要望は既存のフリーソフトを探し、組合せることで満たされることでしょう。 しかし、より細かな要求には答えられない場面も多くあります。

そのような状態に陥いった時、以下の選択肢が考えられます。

  1. 作者に要望を出す
  2. より要望を満たせる他のフリーソフトを探す
  3. あきらめる
  4. 自分で改造する

1-3を選択する人がかなりの割合を占めていることでしょう。

1の手法は、うまく行けば状況が改善されるでしょう。しかし、

といった問題点があります。

2の手法は、運良くそのようなソフトウェアが存在すれば解決しますが、 確実ではありません。

3に至っては、そもそも問題が解決しません。

4の手法であれば、最も望み通りの結果を得ることができます。 しかも、自分があきらめさえしなければ必ず結果を得ることができるのです。

改造のすすめ

1998年頃、私は freeWAIS-sf という全文検索エンジンに、 インテックの石田さんが作成された日本語パッチを当てたものを使っていました。 当時、日本語が扱えて検索用 perl module が存在したのがそれしか なかったからです。柔軟に利用するためには、perl module が必要不可欠でした。

しかし、一点だけ要求にそぐわないところがありました。それは、 インデックス対象の文章がEUCで書かれていることを前提にしていた点です。

しかし、その点を解決する方法は既にありました。京都大学の馬場さんが 作成されたfreeWAIS-sfの日本語パッチです。こちらは、nkfをpipeで呼ぶことで 内部をEUCに統一させ、SJISやISO-2022-JPの文章も扱えるようになっていました。 nkfだけでなく、単語の分割にもkakasiをpipeで呼ぶという手法を取っていました。

一方、石田さんのパッチの方はChaSenのライブラリをリンクし、1つのプロセス の中で処理が完結している分、効率が優れていました。この効率の良さは 私にとって捨てがたいものでした。

そこで、この実装を参考に石田さんのパッチを改良し、インデックス対象の 日本語変換機能を追加しました。これを石田さんにフィードバックし、 自分が作成した実装よりも適切な形に直されて石田さんのパッチに 含めてもらうことができました。

この時に得られた教訓は以下の通りです。

改造をすることで、単にその結果を得ただけでなく、こういった教訓や より良い実装をも得ることができました。改造にはこんなメリットもあります :-)

ライブラリの重要性

NLUG(Nagoya Linux User Group)でWWWベースのFAQ構築システムが 必要になりました。そこで、 既に存在していたFAQ-O-Maticを日本語化することで対応しました。

FAQ-O-Matic自身には検索エンジンが実装されていました。例によって 単語が空白で分割されていることが前提とされた、英語圏にありがちな 実装でした。日本語文章のエンコーディングの統一と、単語分割処理さえ できれば日本語化することができます。

ここで、日本語化freeWAIS-sfのことを思い出しました。日本語化freeWAIS-sf ではChaSenのライブラリを用いることによって単語分割処理を行なっていました。 FAQ-O-Maticはperlで記述されていたので、これをperlから使うことができれば FAQ-O-Maticにも適用できると考えました。

早速実装をし、Text::ChaSen1を作成しました。これはNamazuにも応用され、 それまでpipeでChaSenを呼んで処理していたoverheadが軽減され、 高速に処理できるようになりました。

このことは、ライブラリの重要性を改めて認識するきっかけになりました。 ChaSenがライブラリという形で提供されていたおかげで、freeWAIS-sfでも FAQ-O-MaticでもNamazuでも利用できたのです。

ライブラリ化

Text::ChaSen1による高速化は大きな反響を呼びました。pipeでコマンドを呼んで いたものをライブラリにするだけで、倍近い高速化を達成できたからです。 しかし、Namazuの利用者はChaSenよりもKAKASIを使っている人の方が多く、 その恩恵を得られる人は少数派でした。

このような状況からKAKASIのライブラリ化要望が出るのはごく自然なことです。 それを受け、実装にとりかかりました。

しかし、もともとライブラリ化を見すえた実装になっていないものをライブラリ化 するのは難しい作業でした。KAKASIの場合、運の良いことに入出力が特定の 関数に集約されていたので、その部分のみに着目することでライブラリ化することが できました。

当然のことではありますが、ライブラリ化は設計段階で検討しておかないと 困難である、ということを痛感しました。

Namazuとの関わり

こういったことが重なって、次第にNamazuの改良に関わるようになってゆきました。 このことは、「自分の要求を満たす機能を実装する」ことの実践でもあります。

当時、個人的に欲しいと思っていた機能は以下の通りです。

これらの実装を個人的目標として開発をすすめてゆきました。2000年4月現在、 後者2つが実装できています。

File::MMagic

非textデータ処理の際に必要となるのが、ファイルの自動判別です。

多くの Unix 環境には file というコマンドが存在し、それを用いることで 自動判別を行なうことが可能となっています。しかし、このコマンドはもともと 人間が利用することを前提としているので、機械的な判別には向かない出力しか 行なません。また、単独のコマンドであることは速度の点でも不利です。

そこで、これを実現するためのperl moduleを使うことにしました。 まずCPANを調べ、そのようなmoduleの存在を確認しようとしましたが、 それらしいものはありませんでした。

次に、fj.comp.lang.perlで質問を行ないました。fj.comp.lang.perlは 非常に強力なperl hackerが講読しているニュースグループで、 あるperl hackerの一人から「moduleは知らないが、Perl Power Toolという perlで書かれたツール群の中にfileコマンドがある」という有力な 回答を得ることができました。

早速そのコマンドのソースを取得し、ライセンスを確認しました。 幸いなことにPerl Power Toolのライセンスは非常にゆるく、改造したものを 配布することに制限はありませんでした。そこで、これをベースにperl module を作成しました。

作成したmoduleはFile::MMagicと名付けました。本当はFile::MimeMagicと したかったのですが、名前が長くなりすぎるのは不便だろうという考えから この名前に落着きました。

このモジュールは次のような特徴があります。

magicファイルを内蔵
moduleのみをインストールするだけで即使える
判別結果をMedia Typeで返す
機械的判別が可能
perlのみで実装
インストールにCコンパイラ等が不要
Objectiveな実装
異なるmagicファイルを持ったインスタンスを生成できる

判別結果をMedia Typeで返すためには、その情報を記述したmagicファイルが 必要でした。WWWサーバの1つであるApacheの標準的な配布内容に、 ずばりそのものが含まれていたので、それを利用しました。この際に、File:MMagic はApacheから派生した生成物とみなされるため、The Apache Licenseが適用 されることになりました。

このmoduleはNamazu以外でも有用だろうと思い、CPANに登録することにしました。 このおかげで、いくつかのバグ報告やパッチを得ることができました。

開発に役立つツール達

改造をする上で、さまざまなツール類のお世話になりました。特に 役立ったと思われるものを以下に挙げます。

まとめ

私の言いたいことをまとめると、

ということです。


Satoru Takabayashi