Tokyo Cabinet を触りだけ使ってみた
mixi Engineers’ Blog をみてて、Tokyo Cabinet すげえと思ったので少し触ってみた備忘録。
開発環境
- CentOS5.4 x86_64
Tokyo Cabinetインストール
rpmforge を設定してなかったら設定。
$ wget http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm $ yum clean all; yum list > /dev/null 2>&1
必要なものをインストール
$ sudo yum install lzo.x86_64 lzo-devel.x86_64 zlib.i386 zlib-devel.x86_64 lzma.x86_64 lzma-devel.x86_64 lzma-libs.x86_64 bzip2.x86_64 bzip2-devel.x86_64 bzip2-libs.x86_64
Tokyo Cabinet のインストール
$ wget http://1978th.net/tokyocabinet/tokyocabinet-1.4.41.tar.gz $ tar xvf tokyocabinet-1.4.41.tar.gz $ cd tokyocabinet-1.4.41 $ ./configure $ make $ sudo make install
Tokyo Cabinet のRubyバインディングインストール
$ wget http://1978th.net/tokyocabinet/rubypkg/tokyocabinet-ruby-1.29.tar.gz $ tar xvzf tokyocabinet-ruby-1.29.tar.gz $ cd tokyocabinet-ruby-1.29 $ ruby extconf.rb $ make $ sudo make install
サンプルためしたらエラー
ライブラリの場所がわかんないようだ。
$ ruby -wc hoge.rb /usr/lib/ruby/site_ruby/1.8/x86_64-linux/tokyocabinet.so: libtokyocabinet.so.9: cannot open shared object file: No such file or directory - /usr/lib/ruby/site_ruby/1.8/x86_64-linux/tokyocabinet.so (LoadError) from insert.rb:2 $ ls -l /usr/lib/ruby/site_ruby/1.8/x86_64-linux/tokyocabinet.so -rwxr-xr-x 1 root root 225188 12月 29 03:17 /usr/lib/ruby/site_ruby/1.8/x86_64-linux/tokyocabinet.so $ ldd /usr/lib/ruby/site_ruby/1.8/x86_64-linux/tokyocabinet.so libtokyocabinet.so.9 => not found libbz2.so.1 => /usr/lib64/libbz2.so.1 (0x00002b382a07a000) libz.so.1 => /usr/lib64/libz.so.1 (0x00002b382a28a000) librt.so.1 => /lib64/librt.so.1 (0x00002b382a49f000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b382a6a8000) libm.so.6 => /lib64/libm.so.6 (0x00002b382a8c3000) libc.so.6 => /lib64/libc.so.6 (0x00002b382ab47000) libdl.so.2 => /lib64/libdl.so.2 (0x00002b382ae9e000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00002b382b0a2000) /lib64/ld-linux-x86-64.so.2 (0x0000003e6c400000)
.bashrcにLD_LIBRARY_PATH追加
$ cat ~/.bashrc # .bashrc # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib $ . ~/.bashrc $ ruby -wc hoge.rb
サンプルコード
UNIXのlocateコマンドもどきを書いてみた。
ファイル情報のinsert用
require 'find' require 'tokyocabinet' include TokyoCabinet # create the object hdb = HDB::new # open the database if !hdb.open("slocate.tch", HDB::OWRITER | HDB::OCREAT) ecode = hdb.ecode STDERR.printf("open error: %s\n", hdb.errmsg(ecode)) end # store records ignore = /^\/(proc|dev)/ Find.find("/") {|x| next if x =~ ignore if !hdb.put(x, File.ftype(x)) ecode = hdb.ecode STDERR.printf("put error: %s\n", hdb.errmsg(ecode)) end } # close the database if !hdb.close ecode = hdb.ecode STDERR.printf("close error: %s\n", hdb.errmsg(ecode)) end
ファイルのsearch用
require 'tokyocabinet' include TokyoCabinet (puts "usage: #{__FILE__} [search]"; exit) if ARGV.size == 0 regex = /#{ARGV[0]}/ # create the object hdb = HDB::new # open the database if !hdb.open("slocate.tch", HDB::OREADER) ecode = hdb.ecode STDERR.printf("open error: %s\n", hdb.errmsg(ecode)) exit end # traverse records hdb.iterinit while key = hdb.iternext value = hdb.get(key) printf("%s is %s\n", key, value) if key =~ regex end # close the database if !hdb.close ecode = hdb.ecode STDERR.printf("close error: %s\n", hdb.errmsg(ecode)) end
insert.rbでDBを作ってsearch.rbで検索。
$ ruby insert.rb $ ruby search.rb wtmp /usr/share/doc/vte-0.14.0/utmpwtmp.txt is file /usr/share/man/man3/logwtmp.3.gz is file /usr/share/man/man3/updwtmp.3.gz is file /usr/share/man/man5/wtmp.5.gz is file /usr/share/man/en/man3/updwtmp.3.gz is file /usr/share/man/ja/man3/logwtmp.3.gz is file /usr/share/man/ja/man3/updwtmp.3.gz is file /usr/share/man/ja/man5/wtmp.5.gz is file /var/log/wtmp is file
実際のslocateと比較
$ time ruby search.rb wtmp real 0m0.350s user 0m0.308s sys 0m0.040s $ time locate wtmp real 0m0.076s user 0m0.028s sys 0m0.000s
オレオレ slocate を15分足らずでできるのはすごい、と思いました。