This is a c extension for Ruby to access TokyoTyrant databases. It currently supports key/value, table databases and table queries.
# install tokyocabint and tokyotyrant # after installing tc and tt on linux I had to /sbin/ldconfig (as root) gem sources -a http://gems.github.com sudo gem install actsasflinn-ruby-tokyotyrant
This is not in production but the initial benchmarks are very interesting. Results look closer to the memcached gem than any other tyrant client I’ve seen for Ruby.
-
Key/Value Store: gist.github.com/75212
-
Table Store: gist.github.com/74116
-
Bulk Operations: gist.github.com/83194
-
Bulk Table Operations: gist.github.com/87215
# start tyrant like so: # ttserver example.tch require 'tokyo_tyrant' db = TokyoTyrant::DB.new('127.0.0.1', 1978) db['foo'] = 'Bar' # => "Bar" db['foo'] # => "Bar" db.each{ |k,v| puts [k, v].inspect } # ["foo", "Bar"] # => nil db.mput("1"=>"number_1", "2"=>"number_2", "3"=>"number_3", "4"=>"number_4", "5"=>"number_5") db.mget(1..3) # => {"1"=>"number_1", "2"=>"number_2", "3"=>"number_3"}
# start tyrant like so: # ttserver example.tct require 'tokyo_tyrant' t = TokyoTyrant::Table.new('127.0.0.1', 1978) t['bar'] = { :baz => 'box' } # => { :baz => 'box' } t['bar'] # => { :baz => 'box' } t.each{ |k,v| puts [k, v].inspect } # ["bar", {:baz=>"box"}] # => nil # bulk operations h = {} 100.times do |i| h[i] = { :name => 'Pat', :sex => i % 2 > 0 ? 'male' : 'female' } end t.mput(h) t.mget(0..3) # => {"0"=>{:name=>"Pat", :sex=>"female"}, "1"=>{:name=>"Pat", :sex=>"male"}, "2"=>{:name=>"Pat", :sex=>"female"}, "3"=>{:name=>"Pat", :sex=>"male"}}
require 'tokyo_tyrant' t = TokyoTyrant::Table.new('127.0.0.1', 1978) 100.times do |i| t[i] = { 'name' => "Pat #{i}", 'sex' => i % 2 > 0 ? 'male' : 'female' } end q = t.query q.condition('sex', :streq, 'male') q.limit(5) # Get a list of IDs ids = q.search # => ["1", "3", "5", "7", "9"] q.order_by(:name, :strdesc) ids = q.search # => ["99", "97", "95", "93", "91"] # Get the actual records q.get # => [{:__id=>"99", :sex=>"male", :name=>"Pat 99"}, {:__id=>"97", :sex=>"male", :name=>"Pat 97"}, {:__id=>"95", :sex=>"male", :name=>"Pat 95"}, {:__id=>"93", :sex=>"male", :name=>"Pat 93"}, {:__id=>"91", :sex=>"male", :name=>"Pat 91"}] # Alternative Syntax (better) # Query using a block t.query{ |q| q.condition('sex', :streq, 'male') q.limit(5) } # => ["1", "3", "5", "7", "9"] # Get records for a query t.find{ |q| q.condition('sex', :streq, 'male') q.limit(5) } # => [{:sex=>"male", :name=>"Pat 1", :__id=>"1"}, {:sex=>"male", :name=>"Pat 3", :__id=>"3"}, {:sex=>"male", :name=>"Pat 5", :__id=>"5"}, {:sex=>"male", :name=>"Pat 7", :__id=>"7"}, {:sex=>"male", :name=>"Pat 9", :__id=>"9"}] # Prepare but don't run a search, return a prepared query object q = t.prepare_query{ |q| q.condition('sex', :streq, 'male') q.limit(5) } # => #<TokyoTyrant::Query:0x247c14 @rdb=#<Object:0x2800a0>, @rdbquery=#<Object:0x247c00>> q.search # => ["1", "3", "5", "7", "9"] q.get # => [{:sex=>"male", :name=>"Pat 1", :__id=>"1"}, {:sex=>"male", :name=>"Pat 3", :__id=>"3"}, {:sex=>"male", :name=>"Pat 5", :__id=>"5"}, {:sex=>"male", :name=>"Pat 7", :__id=>"7"}, {:sex=>"male", :name=>"Pat 9", :__id=>"9"}]
-
implement get_reverse for has_value?
-
fix up and test extensions