rufus-tokyo 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGELOG.txt +6 -0
- data/Rakefile +91 -0
- data/doc/decision_table.numbers +0 -0
- data/lib/rufus/edo/README.txt +101 -0
- data/lib/rufus/edo/tabcore.rb +1 -3
- data/lib/rufus/tokyo.rb +1 -2
- data/lib/rufus/tokyo/cabinet/lib.rb +4 -7
- data/lib/rufus/tokyo/cabinet/table.rb +10 -13
- data/lib/rufus/tokyo/cabinet/util.rb +4 -1
- data/lib/rufus/tokyo/hmethods.rb +4 -4
- data/lib/rufus/tokyo/outlen.rb +5 -1
- data/lib/rufus/tokyo/tyrant/abstract.rb +8 -0
- data/lib/rufus/tokyo/tyrant/lib.rb +6 -6
- data/lib/rufus/tokyo/tyrant/table.rb +9 -1
- data/lib/rufus/tokyo/version.rb +32 -0
- data/rufus-tokyo.gemspec +135 -0
- data/spec/cabinet_btree_spec.rb +92 -0
- data/spec/cabinet_fixed_spec.rb +33 -0
- data/spec/cabinet_spec.rb +291 -0
- data/spec/cabinetconfig_spec.rb +82 -0
- data/spec/dystopia_core_spec.rb +124 -0
- data/spec/edo_cabinet_btree_spec.rb +123 -0
- data/spec/edo_cabinet_fixed_spec.rb +42 -0
- data/spec/edo_cabinet_spec.rb +286 -0
- data/spec/edo_ntyrant_spec.rb +224 -0
- data/spec/edo_ntyrant_table_spec.rb +296 -0
- data/spec/edo_table_spec.rb +292 -0
- data/spec/hmethods_spec.rb +73 -0
- data/spec/incr.lua +23 -0
- data/spec/openable_spec.rb +51 -0
- data/spec/shared_abstract_spec.rb +426 -0
- data/spec/shared_table_spec.rb +675 -0
- data/spec/shared_tyrant_spec.rb +42 -0
- data/spec/spec_base.rb +23 -0
- data/spec/start_tyrants.sh +28 -0
- data/spec/stop_tyrants.sh +9 -0
- data/spec/table_spec.rb +267 -0
- data/spec/tyrant_spec.rb +218 -0
- data/spec/tyrant_table_spec.rb +298 -0
- data/spec/util_list_spec.rb +197 -0
- data/spec/util_map_spec.rb +130 -0
- data/tasks/dev.rb +70 -0
- data/test/bm0.rb +353 -0
- data/test/bm1_compression.rb +54 -0
- data/test/con0.rb +30 -0
- data/test/mem.rb +49 -0
- data/test/mem1.rb +44 -0
- data/test/readme0.rb +17 -0
- data/test/readme1.rb +21 -0
- data/test/readme2.rb +15 -0
- data/test/readme3.rb +24 -0
- data/test/readmes_test.sh +17 -0
- metadata +81 -21
- data/MIGRATED.txt +0 -1
data/.gitignore
ADDED
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
= rufus-tokyo CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-tokyo - 1.0.4 released 2009/12/25
|
6
|
+
|
7
|
+
- bug : memory leak, gotten values not freed
|
8
|
+
- todo : Rufus::Tokyo::Tyrant and TyrantTable now reconnets (120 seconds)
|
9
|
+
|
10
|
+
|
5
11
|
== rufus-tokyo - 1.0.3 released 2009/11/16
|
6
12
|
|
7
13
|
- bug : newer versions of FFI have [undocumented] bool type. Adapted.
|
data/Rakefile
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require 'lib/rufus/tokyo/version.rb'
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
|
8
|
+
|
9
|
+
#
|
10
|
+
# CLEAN
|
11
|
+
|
12
|
+
require 'rake/clean'
|
13
|
+
CLEAN.include('pkg', 'tmp', 'html')
|
14
|
+
task :default => [ :clean ]
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# GEM
|
19
|
+
|
20
|
+
require 'jeweler'
|
21
|
+
|
22
|
+
Jeweler::Tasks.new do |gem|
|
23
|
+
|
24
|
+
gem.version = Rufus::Tokyo::VERSION
|
25
|
+
gem.name = 'rufus-tokyo'
|
26
|
+
|
27
|
+
gem.summary =
|
28
|
+
'ruby-ffi based lib to access Tokyo Cabinet, Tyrant and Dystopia'
|
29
|
+
gem.description = %{
|
30
|
+
Ruby-ffi based lib to access Tokyo Cabinet and Tyrant.
|
31
|
+
|
32
|
+
The ffi-based structures are available via the Rufus::Tokyo namespace.
|
33
|
+
There is a Rufus::Edo namespace that interfaces with Hirabayashi-san's native Ruby interface, and whose API is equal to the Rufus::Tokyo one.
|
34
|
+
|
35
|
+
Finally rufus-tokyo includes ffi-based interfaces to Tokyo Dystopia (thanks to Jeremy Hinegardner).
|
36
|
+
}
|
37
|
+
|
38
|
+
gem.email = 'jmettraux@gmail.com'
|
39
|
+
gem.homepage = 'http://github.com/jmettraux/rufus-tokyo/'
|
40
|
+
|
41
|
+
gem.authors = [
|
42
|
+
'John Mettraux', 'Zev Blut', 'Jeremy Hinegardner', 'James Edward Gray II' ]
|
43
|
+
|
44
|
+
gem.rubyforge_project = 'rufus'
|
45
|
+
|
46
|
+
gem.test_file = 'spec/spec.rb'
|
47
|
+
|
48
|
+
gem.add_dependency 'ffi'
|
49
|
+
gem.add_development_dependency 'yard', '>= 0'
|
50
|
+
|
51
|
+
#gem.files = Dir['lib/**/*.rb'] + Dir['*.txt'] - [ 'lib/tokyotyrant.rb' ]
|
52
|
+
#gem.files.reject! { |fn| fn == 'lib/tokyotyrant.rb' }
|
53
|
+
|
54
|
+
# gemspec spec : http://www.rubygems.org/read/chapter/20
|
55
|
+
end
|
56
|
+
Jeweler::GemcutterTasks.new
|
57
|
+
|
58
|
+
|
59
|
+
#
|
60
|
+
# DOC
|
61
|
+
|
62
|
+
begin
|
63
|
+
|
64
|
+
require 'yard'
|
65
|
+
|
66
|
+
YARD::Rake::YardocTask.new do |doc|
|
67
|
+
doc.options = [
|
68
|
+
'-o', 'html/rufus-tokyo', '--title',
|
69
|
+
"rufus-tokyo #{Rufus::Tokyo::VERSION}"
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
rescue LoadError
|
74
|
+
|
75
|
+
task :yard do
|
76
|
+
abort "YARD is not available : sudo gem install yard"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
#
|
82
|
+
# TO THE WEB
|
83
|
+
|
84
|
+
task :upload_website => [ :clean, :yard ] do
|
85
|
+
|
86
|
+
account = 'jmettraux@rubyforge.org'
|
87
|
+
webdir = '/var/www/gforge-projects/rufus'
|
88
|
+
|
89
|
+
sh "rsync -azv -e ssh html/rufus-tokyo #{account}:#{webdir}/"
|
90
|
+
end
|
91
|
+
|
Binary file
|
@@ -0,0 +1,101 @@
|
|
1
|
+
|
2
|
+
= Rufus::Edo
|
3
|
+
|
4
|
+
wrapping Hirabayashi-san's 'native' ruby bindings into a rubiyst-friendly set of Ruby classes.
|
5
|
+
|
6
|
+
In order to use Rufus::Edo, you have to have the libtokyocabinet dynamic library installed on your system :
|
7
|
+
|
8
|
+
http://openwferu.rubyforge.org/tokyo.html
|
9
|
+
|
10
|
+
Then you can install the 'native' C bindings.
|
11
|
+
|
12
|
+
NOTE : I have only tested those native bindings with Ruby 1.8.6. To run them with JRuby, the best option is Rufus::Tokyo and its FFI bindings.
|
13
|
+
|
14
|
+
NOTE : the Ruby tyrant library provided by Hirabayashi-san is not a C binding, it's a pure Ruby connector. It is slower than Rufus::Tokyo::Tyrant and Rufus::Tokyo::TyrantTable, but the advantage is that there is no need to install cabinet and tyrant C libraries to connect your Ruby code to your Tokyo Tyrant.
|
15
|
+
|
16
|
+
|
17
|
+
== installation of the 'native' C bindings
|
18
|
+
|
19
|
+
=== directly from http://1978th.net/tokyocabinet/
|
20
|
+
|
21
|
+
Get the tokyocabinet-ruby package at :
|
22
|
+
|
23
|
+
http://1978th.net/tokyocabinet/rubypkg/
|
24
|
+
|
25
|
+
unpack it :
|
26
|
+
|
27
|
+
tar xzvf tokyocabinet-ruby-1.29.tar.gz
|
28
|
+
cd tokyocabinet-ruby-1.29
|
29
|
+
|
30
|
+
and then, as described at : http://tokyocabinet.sourceforge.net/rubydoc/
|
31
|
+
|
32
|
+
ruby extconf.rb
|
33
|
+
make
|
34
|
+
sudo make install
|
35
|
+
|
36
|
+
|
37
|
+
== Rufus::Edo::Cabinet
|
38
|
+
|
39
|
+
require 'rufus/edo' # sudo gem install rufus-tokyo
|
40
|
+
|
41
|
+
db = Rufus::Edo::Cabinet.new('data.tch')
|
42
|
+
|
43
|
+
db['a'] = 'alpha'
|
44
|
+
|
45
|
+
# ...
|
46
|
+
|
47
|
+
db.close
|
48
|
+
|
49
|
+
|
50
|
+
== Rufus::Edo::Table
|
51
|
+
|
52
|
+
require 'rufus/edo'
|
53
|
+
|
54
|
+
db = Rufus::Edo::Table.new('data.tct')
|
55
|
+
|
56
|
+
db['customer1'] = { 'name' => 'Taira no Kyomori', 'age' => '55' }
|
57
|
+
|
58
|
+
# ...
|
59
|
+
|
60
|
+
db.close
|
61
|
+
|
62
|
+
|
63
|
+
== tyrant
|
64
|
+
|
65
|
+
Hirabayashi-san's pure Ruby gem for accessing Tokyo Tyrant can be installed with :
|
66
|
+
|
67
|
+
sudo gem install careo-tokyotyrant --source http://gems.github.com
|
68
|
+
|
69
|
+
It's also available at :
|
70
|
+
|
71
|
+
http://sourceforge.net/project/showfiles.php?group_id=200242
|
72
|
+
http://github.com/careo/tokyotyrant-ruby
|
73
|
+
|
74
|
+
|
75
|
+
== Rufus::Edo::NetTyrant
|
76
|
+
|
77
|
+
Note : 'NetTyrant' instead of 'Tyrant' to clearly show that this class isn't a C binding but a simple [pure Ruby] network implementation of a connection to a Tyrant.
|
78
|
+
|
79
|
+
|
80
|
+
require 'rufus/edo/ntyrant'
|
81
|
+
|
82
|
+
db = Rufus::Edo::NetTyrant.new('127.0.0.1', 45000)
|
83
|
+
|
84
|
+
db['a'] = 'alpha'
|
85
|
+
|
86
|
+
puts db['a]
|
87
|
+
# => 'alpha'
|
88
|
+
|
89
|
+
db.close
|
90
|
+
|
91
|
+
|
92
|
+
== Rufus::Edo::NetTyrantTable
|
93
|
+
|
94
|
+
require 'rufus/edo/ntyrant'
|
95
|
+
|
96
|
+
t = Rufus::Edo::NetTyrantTable.new('127.0.0.1', 44502)
|
97
|
+
|
98
|
+
t['client0'] = { 'name' => 'Heike no Kyomori', 'country' => 'jp' }
|
99
|
+
|
100
|
+
t.close
|
101
|
+
|
data/lib/rufus/edo/tabcore.rb
CHANGED
data/lib/rufus/tokyo.rb
CHANGED
@@ -29,8 +29,6 @@ require 'ffi' # sudo gem install ffi
|
|
29
29
|
module Rufus
|
30
30
|
module Tokyo
|
31
31
|
|
32
|
-
VERSION = '1.0.3'
|
33
|
-
|
34
32
|
#
|
35
33
|
# A common error class
|
36
34
|
#
|
@@ -51,6 +49,7 @@ module Tokyo
|
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
52
|
+
require 'rufus/tokyo/version'
|
54
53
|
require 'rufus/tokyo/cabinet/lib'
|
55
54
|
require 'rufus/tokyo/cabinet/util'
|
56
55
|
require 'rufus/tokyo/cabinet/abstract'
|
@@ -46,7 +46,7 @@ module Rufus::Tokyo
|
|
46
46
|
rescue LoadError => le
|
47
47
|
raise(
|
48
48
|
"didn't find Tokyo Cabinet libs on your system. " +
|
49
|
-
"Please install Tokyo Cabinet (http://
|
49
|
+
"Please install Tokyo Cabinet (http://1978th.net/tokyocabinet/) " +
|
50
50
|
"(see also http://openwferu.rubyforge.org/tokyo.html)"
|
51
51
|
)
|
52
52
|
end
|
@@ -66,6 +66,8 @@ module Rufus::Tokyo
|
|
66
66
|
#
|
67
67
|
attfunc :tcfree, [ :pointer ], :void
|
68
68
|
|
69
|
+
attfunc :free, [ :pointer ], :void
|
70
|
+
|
69
71
|
#
|
70
72
|
# tcadb functions
|
71
73
|
#
|
@@ -177,12 +179,7 @@ module Rufus::Tokyo
|
|
177
179
|
callback :TDBQRYPROC, [:pointer, :int, :pointer, :pointer], :int
|
178
180
|
attfunc :qry_proc, :tctdbqryproc, [ :pointer, :TDBQRYPROC, :pointer], :bool
|
179
181
|
|
180
|
-
|
181
|
-
begin # since TC 1.4.10
|
182
|
-
attfunc :qry_setmax, :tctdbqrysetmax, [ :pointer, :int ], :void
|
183
|
-
rescue FFI::NotFoundError => nfe
|
184
|
-
attfunc :qry_setlimit, :tctdbqrysetlimit, [ :pointer, :int, :int ], :void
|
185
|
-
end
|
182
|
+
attfunc :qry_setlimit, :tctdbqrysetlimit, [ :pointer, :int, :int ], :void
|
186
183
|
|
187
184
|
attfunc :qry_search, :tctdbqrysearch, [ :pointer ], :pointer
|
188
185
|
attfunc :qry_searchout, :tctdbqrysearchout, [ :pointer ], :bool
|
@@ -43,8 +43,7 @@ module Rufus::Tokyo
|
|
43
43
|
# require 'rubygems'
|
44
44
|
# require 'rufus/tokyo/cabinet/table'
|
45
45
|
#
|
46
|
-
# t = Rufus::Tokyo::Table.new('table.
|
47
|
-
# # '.tdb' suffix is a must
|
46
|
+
# t = Rufus::Tokyo::Table.new('table.tct')
|
48
47
|
#
|
49
48
|
# t['pk0'] = { 'name' => 'alfred', 'age' => '22' }
|
50
49
|
# t['pk1'] = { 'name' => 'bob', 'age' => '18' }
|
@@ -76,10 +75,10 @@ module Rufus::Tokyo
|
|
76
75
|
#
|
77
76
|
# For example,
|
78
77
|
#
|
79
|
-
# t = Rufus::Tokyo::Table.new('table.
|
80
|
-
# # '.
|
78
|
+
# t = Rufus::Tokyo::Table.new('table.tct')
|
79
|
+
# # '.tct' suffix is a must
|
81
80
|
#
|
82
|
-
# will create the table.
|
81
|
+
# will create the table.tct (or simply open it if already present)
|
83
82
|
# and make sure we have write access to it.
|
84
83
|
#
|
85
84
|
# == parameters
|
@@ -118,11 +117,11 @@ module Rufus::Tokyo
|
|
118
117
|
#
|
119
118
|
# Some examples :
|
120
119
|
#
|
121
|
-
# t = Rufus::Tokyo::Table.new('table.
|
122
|
-
# t = Rufus::Tokyo::Table.new('table.
|
123
|
-
# t = Rufus::Tokyo::Table.new('table.
|
124
|
-
# t = Rufus::Tokyo::Table.new('table.
|
125
|
-
# t = Rufus::Tokyo::Table.new('table.
|
120
|
+
# t = Rufus::Tokyo::Table.new('table.tct')
|
121
|
+
# t = Rufus::Tokyo::Table.new('table.tct#mode=r')
|
122
|
+
# t = Rufus::Tokyo::Table.new('table.tct', :mode => 'r')
|
123
|
+
# t = Rufus::Tokyo::Table.new('table.tct#opts=ld#mode=r')
|
124
|
+
# t = Rufus::Tokyo::Table.new('table.tct', :opts => 'ld', :mode => 'r')
|
126
125
|
#
|
127
126
|
def initialize (path, params={})
|
128
127
|
|
@@ -722,9 +721,7 @@ module Rufus::Tokyo
|
|
722
721
|
#
|
723
722
|
def limit (i, offset=-1)
|
724
723
|
|
725
|
-
lib.
|
726
|
-
lib.qry_setlimit(@query, i, offset) :
|
727
|
-
lib.qry_setmax(@query, i)
|
724
|
+
lib.qry_setlimit(@query, i, offset)
|
728
725
|
end
|
729
726
|
|
730
727
|
# Sets the sort order for the result of the query
|
@@ -63,11 +63,14 @@ module Rufus::Tokyo
|
|
63
63
|
|
64
64
|
return nil if out.address == 0
|
65
65
|
|
66
|
-
|
66
|
+
out.get_bytes(0, outlen.get_int(0))
|
67
67
|
|
68
68
|
ensure
|
69
69
|
|
70
70
|
outlen.free
|
71
|
+
|
72
|
+
#clib.free(out)
|
73
|
+
# uncommenting that wreaks havoc
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
data/lib/rufus/tokyo/hmethods.rb
CHANGED
@@ -59,19 +59,19 @@ module Tokyo
|
|
59
59
|
# Our classical 'each'
|
60
60
|
#
|
61
61
|
def each
|
62
|
-
#
|
62
|
+
#
|
63
63
|
# drop to Edo's C API calls to avoid two-step iteration
|
64
64
|
# (keys() then each())
|
65
|
-
#
|
65
|
+
#
|
66
66
|
if defined?(@db) and %w[iterinit iternext].all? { |m| @db.respond_to?(m) }
|
67
67
|
@db.iterinit
|
68
68
|
while k = @db.iternext
|
69
69
|
yield(k, self[k])
|
70
70
|
end
|
71
|
-
#
|
71
|
+
#
|
72
72
|
# drop to Tokyo's FFI calls to avoid two-step iteration
|
73
73
|
# (keys() then each())
|
74
|
-
#
|
74
|
+
#
|
75
75
|
elsif self.class.name != "Rufus::Tokyo::Table" and # use String for Edo
|
76
76
|
defined?(@db) and
|
77
77
|
respond_to?(:lib) and
|
data/lib/rufus/tokyo/outlen.rb
CHANGED
@@ -37,9 +37,13 @@ module Rufus::Tokyo
|
|
37
37
|
out = lib.send(method, *args)
|
38
38
|
|
39
39
|
return nil if out.address == 0
|
40
|
-
|
40
|
+
|
41
|
+
out.get_bytes(0, outlen.get_int(0))
|
42
|
+
|
41
43
|
ensure
|
42
44
|
outlen.free
|
45
|
+
#lib.tcfree(out)
|
46
|
+
lib.free(out)
|
43
47
|
end
|
44
48
|
end
|
45
49
|
end
|
@@ -114,6 +114,14 @@ module Rufus::Tokyo
|
|
114
114
|
|
115
115
|
self.default = params[:default]
|
116
116
|
@default_proc ||= params[:default_proc]
|
117
|
+
|
118
|
+
#
|
119
|
+
# timeout and reconnect
|
120
|
+
|
121
|
+
# defaults to two minutes
|
122
|
+
|
123
|
+
timeout = params[:timeout] || 120.0
|
124
|
+
lib.tcrdbtune(@db, timeout, 1)
|
117
125
|
end
|
118
126
|
|
119
127
|
# Using the tyrant lib
|
@@ -44,7 +44,7 @@ module Rufus::Tokyo
|
|
44
44
|
rescue LoadError => le
|
45
45
|
raise(
|
46
46
|
"didn't find Tokyo Tyrant libs on your system. " +
|
47
|
-
"Please install Tokyo Tyrant (http://
|
47
|
+
"Please install Tokyo Tyrant (http://1978th.net/tokyotyrant/) " +
|
48
48
|
"(see also http://openwferu.rubyforge.org/tokyo.html)"
|
49
49
|
)
|
50
50
|
end
|
@@ -54,6 +54,8 @@ module Rufus::Tokyo
|
|
54
54
|
alias :attfunc :attach_function
|
55
55
|
end
|
56
56
|
|
57
|
+
attfunc :free, [ :pointer ], :void
|
58
|
+
|
57
59
|
# http://1978th.net/tokyotyrant/spex.html#tcrdbapi
|
58
60
|
|
59
61
|
#
|
@@ -63,6 +65,8 @@ module Rufus::Tokyo
|
|
63
65
|
|
64
66
|
attfunc :tcrdbstat, [ :pointer ], :string
|
65
67
|
|
68
|
+
attfunc :tcrdbtune, [ :pointer, :double, :int ], :bool
|
69
|
+
|
66
70
|
attfunc :tcrdbopen, [ :pointer, :string, :int ], :bool
|
67
71
|
attfunc :abs_close, :tcrdbclose, [ :pointer ], :bool
|
68
72
|
|
@@ -138,11 +142,7 @@ module Rufus::Tokyo
|
|
138
142
|
attfunc :qry_addcond, :tcrdbqryaddcond, [ :pointer, :string, :int, :string ], :void
|
139
143
|
attfunc :qry_setorder, :tcrdbqrysetorder, [ :pointer, :string, :int ], :void
|
140
144
|
|
141
|
-
|
142
|
-
attfunc :qry_setmax, :tcrdbqrysetmax, [ :pointer, :int ], :void
|
143
|
-
rescue FFI::NotFoundError => nfe
|
144
|
-
attfunc :qry_setlimit, :tcrdbqrysetlimit, [ :pointer, :int, :int ], :void
|
145
|
-
end
|
145
|
+
attfunc :qry_setlimit, :tcrdbqrysetlimit, [ :pointer, :int, :int ], :void
|
146
146
|
|
147
147
|
attfunc :qry_search, :tcrdbqrysearch, [ :pointer ], :pointer
|
148
148
|
attfunc :qry_searchout, :tcrdbqrysearchout, [ :pointer ], :bool
|
@@ -75,7 +75,7 @@ module Rufus::Tokyo
|
|
75
75
|
# t['client0'] = { 'name' => 'Theodore Roosevelt', 'country' => 'usa' }
|
76
76
|
# t.close
|
77
77
|
#
|
78
|
-
def initialize (host, port=0)
|
78
|
+
def initialize (host, port=0, params={})
|
79
79
|
|
80
80
|
@db = lib.tcrdbnew
|
81
81
|
|
@@ -95,6 +95,14 @@ module Rufus::Tokyo
|
|
95
95
|
end
|
96
96
|
|
97
97
|
@default_proc = nil
|
98
|
+
|
99
|
+
#
|
100
|
+
# timeout and reconnect
|
101
|
+
|
102
|
+
# defaults to two minutes
|
103
|
+
|
104
|
+
timeout = params[:timeout] || 120.0
|
105
|
+
lib.tcrdbtune(@db, timeout, 1)
|
98
106
|
end
|
99
107
|
|
100
108
|
#
|