読者です 読者をやめる 読者になる 読者になる

harry’s memorandum

おれおれメモ

Tokyo Cabinet を触りだけ使ってみた

ruby

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分足らずでできるのはすごい、と思いました。