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.
Files changed (55) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG.txt +6 -0
  3. data/Rakefile +91 -0
  4. data/doc/decision_table.numbers +0 -0
  5. data/lib/rufus/edo/README.txt +101 -0
  6. data/lib/rufus/edo/tabcore.rb +1 -3
  7. data/lib/rufus/tokyo.rb +1 -2
  8. data/lib/rufus/tokyo/cabinet/lib.rb +4 -7
  9. data/lib/rufus/tokyo/cabinet/table.rb +10 -13
  10. data/lib/rufus/tokyo/cabinet/util.rb +4 -1
  11. data/lib/rufus/tokyo/hmethods.rb +4 -4
  12. data/lib/rufus/tokyo/outlen.rb +5 -1
  13. data/lib/rufus/tokyo/tyrant/abstract.rb +8 -0
  14. data/lib/rufus/tokyo/tyrant/lib.rb +6 -6
  15. data/lib/rufus/tokyo/tyrant/table.rb +9 -1
  16. data/lib/rufus/tokyo/version.rb +32 -0
  17. data/rufus-tokyo.gemspec +135 -0
  18. data/spec/cabinet_btree_spec.rb +92 -0
  19. data/spec/cabinet_fixed_spec.rb +33 -0
  20. data/spec/cabinet_spec.rb +291 -0
  21. data/spec/cabinetconfig_spec.rb +82 -0
  22. data/spec/dystopia_core_spec.rb +124 -0
  23. data/spec/edo_cabinet_btree_spec.rb +123 -0
  24. data/spec/edo_cabinet_fixed_spec.rb +42 -0
  25. data/spec/edo_cabinet_spec.rb +286 -0
  26. data/spec/edo_ntyrant_spec.rb +224 -0
  27. data/spec/edo_ntyrant_table_spec.rb +296 -0
  28. data/spec/edo_table_spec.rb +292 -0
  29. data/spec/hmethods_spec.rb +73 -0
  30. data/spec/incr.lua +23 -0
  31. data/spec/openable_spec.rb +51 -0
  32. data/spec/shared_abstract_spec.rb +426 -0
  33. data/spec/shared_table_spec.rb +675 -0
  34. data/spec/shared_tyrant_spec.rb +42 -0
  35. data/spec/spec_base.rb +23 -0
  36. data/spec/start_tyrants.sh +28 -0
  37. data/spec/stop_tyrants.sh +9 -0
  38. data/spec/table_spec.rb +267 -0
  39. data/spec/tyrant_spec.rb +218 -0
  40. data/spec/tyrant_table_spec.rb +298 -0
  41. data/spec/util_list_spec.rb +197 -0
  42. data/spec/util_map_spec.rb +130 -0
  43. data/tasks/dev.rb +70 -0
  44. data/test/bm0.rb +353 -0
  45. data/test/bm1_compression.rb +54 -0
  46. data/test/con0.rb +30 -0
  47. data/test/mem.rb +49 -0
  48. data/test/mem1.rb +44 -0
  49. data/test/readme0.rb +17 -0
  50. data/test/readme1.rb +21 -0
  51. data/test/readme2.rb +15 -0
  52. data/test/readme3.rb +24 -0
  53. data/test/readmes_test.sh +17 -0
  54. metadata +81 -21
  55. data/MIGRATED.txt +0 -1
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ ext/*
2
+ tmp/*
3
+ pkg/*
4
+ *~
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
+
@@ -533,9 +533,7 @@ module Rufus::Edo
533
533
  #
534
534
  def limit (i, offset=-1)
535
535
 
536
- @query.respond_to?(:setlimit) ?
537
- @query.setlimit(i, offset) :
538
- @query.setmax(i)
536
+ @query.setlimit(i, offset)
539
537
  end
540
538
 
541
539
  # Sets the sort order for the result of the query
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://tokyocabinet.sf.net) " +
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.tdb', :create, :write)
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.tdb')
80
- # # '.tdb' suffix is a must
78
+ # t = Rufus::Tokyo::Table.new('table.tct')
79
+ # # '.tct' suffix is a must
81
80
  #
82
- # will create the table.tdb (or simply open it if already present)
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.tdb')
122
- # t = Rufus::Tokyo::Table.new('table.tdb#mode=r')
123
- # t = Rufus::Tokyo::Table.new('table.tdb', :mode => 'r')
124
- # t = Rufus::Tokyo::Table.new('table.tdb#opts=ld#mode=r')
125
- # t = Rufus::Tokyo::Table.new('table.tdb', :opts => 'ld', :mode => 'r')
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.respond_to?(:qry_setlimit) ?
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
- return out.get_bytes(0, outlen.get_int(0))
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
 
@@ -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
@@ -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
- return out.get_bytes(0, outlen.get_int(0))
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://tokyocabinet.sf.net) " +
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
- begin
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
  #