rufus-tokyo 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,163 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ #
26
+ # "made in Japan"
27
+ #
28
+ # jmettraux@gmail.com
29
+ #
30
+
31
+ module Rufus
32
+ module Tokyo
33
+
34
+ #
35
+ # Methods for setting up / tuning a Cabinet.
36
+ #
37
+ module CabinetConfig
38
+
39
+ protected
40
+
41
+ #
42
+ # Given a path, a hash of parameters and a suffix,
43
+ #
44
+ # a) makes sure that the path has the given suffix or raises an exception
45
+ # b) gathers params found in the path (#) or in params
46
+ # c) determines the config as set by the parameters
47
+ #
48
+ # Suffix is optional, if present, it will be enforced.
49
+ #
50
+ def determine_conf (path, params, required_type=nil)
51
+
52
+ if path.index('#')
53
+
54
+ ss = path.split('#')
55
+ path = ss.shift
56
+
57
+ ss.each { |p| pp = p.split('='); params[pp[0]] = pp[1] }
58
+ end
59
+
60
+ params = params.inject({}) { |h, (k, v)| h[k.to_sym] = v; h }
61
+
62
+ [
63
+ {
64
+ :params => params,
65
+ :mode => determine_open_mode(params),
66
+ :mutex => (params[:mutex].to_s == 'true'),
67
+ #:indexes => params[:idx] || params[:indexes],
68
+ :xmsiz => (params[:xmsiz] || 67108864).to_i,
69
+ },
70
+ determine_type_and_path(path, params, required_type),
71
+ determine_tuning_values(params),
72
+ determine_cache_values(params)
73
+
74
+ ].inject({}) { |h, hh| h.merge(hh) }
75
+ end
76
+
77
+ def determine_open_mode (params) #:nodoc#
78
+
79
+ mode = params[:mode].to_s
80
+ mode = 'wc' if mode.size < 1
81
+
82
+ {
83
+ 'r' => (1 << 0), # open as a reader
84
+ 'w' => (1 << 1), # open as a writer
85
+ 'c' => (1 << 2), # writer creating
86
+ 't' => (1 << 3), # writer truncating
87
+ 'e' => (1 << 4), # open without locking
88
+ 'f' => (1 << 5), # lock without blocking
89
+ 's' => (1 << 6), # synchronize every transaction (tctdb.h)
90
+
91
+ }.inject(0) { |r, (c, v)|
92
+
93
+ r = r | v if mode.index(c); r
94
+ }
95
+ end
96
+
97
+ def determine_tuning_values (params) #:nodoc#
98
+
99
+ o = params[:opts] || ''
100
+ o = {
101
+ 'l' => 1 << 0, # large
102
+ 'd' => 1 << 1, # deflate
103
+ 'b' => 1 << 2, # bzip2
104
+ 't' => 1 << 3, # tcbs
105
+ 'x' => 1 << 4
106
+ }.inject(0) { |i, (k, v)| i = i | v if o.index(k); i }
107
+
108
+ {
109
+ :bnum => (params[:bnum] || 131071).to_i,
110
+ :apow => (params[:apow] || 4).to_i,
111
+ :fpow => (params[:fpow] || 10).to_i,
112
+ :opts => o,
113
+
114
+ :lmemb => (params[:lmemb] || 128).to_i,
115
+ # number of members in each leaf page (:btree)
116
+ :nmemb => (params[:nmemb] || 256).to_i,
117
+ # number of members in each non-leaf page (:btree)
118
+
119
+ :width => (params[:width] || 255).to_i,
120
+ # width of the value of each record (:fixed)
121
+ :limsiz => (params[:limsiz] || 26_8435_456).to_i
122
+ # limit size of the database file (:fixed)
123
+ }
124
+ end
125
+
126
+ def determine_cache_values (params) #:nodoc#
127
+
128
+ {
129
+ :rcnum => params[:rcnum].to_i,
130
+ :lcnum => (params[:lcnum] || 2048).to_i,
131
+ :ncnum => (params[:ncnum] || 512).to_i
132
+ }
133
+ end
134
+
135
+ CABINET_SUFFIXES = {
136
+ :hash => '.tch', :btree => '.tcb', :fixed => '.tcf', :table => '.tct'
137
+ }
138
+
139
+ CABINET_TYPES = CABINET_SUFFIXES.invert
140
+
141
+ def determine_type_and_path (path, params, required_type) #:nodoc#
142
+
143
+ type = required_type || params[:type]
144
+ ext = File.extname(path)
145
+
146
+ if ext == ''
147
+ suffix = CABINET_SUFFIXES[type]
148
+ path = path + suffix
149
+ else
150
+ suffix = ext
151
+ type ||= CABINET_TYPES[ext]
152
+ end
153
+
154
+ raise "path '#{path}' must be suffixed with #{suffix}" \
155
+ if suffix and File.extname(path) != suffix
156
+
157
+ { :path => path, :type => type }
158
+ end
159
+ end
160
+
161
+ end
162
+ end
163
+
@@ -22,18 +22,24 @@
22
22
  #++
23
23
  #
24
24
 
25
- module Rufus
26
- module Tokyo
25
+ #
26
+ # "made in Japan"
27
+ #
28
+ # jmettraux@gmail.com
29
+ #
27
30
 
28
- #
29
- # An error for Dystopia
30
- #
31
- class DystopianError < RuntimeError
32
- def new (error_code)
33
- super("tokyo dystopia error #{error_code}")
34
- end
35
- end
31
+ require 'rufus/tokyo'
36
32
 
33
+
34
+ module Rufus::Tokyo
35
+
36
+ #
37
+ # An error for Dystopia
38
+ #
39
+ class DystopianError < RuntimeError
40
+ def new (error_code)
41
+ super("tokyo dystopia error #{error_code}")
42
+ end
37
43
  end
38
44
  end
39
45
 
@@ -28,44 +28,43 @@
28
28
  # jmettraux@gmail.com
29
29
  #
30
30
 
31
- module Rufus
32
- module Tokyo
31
+ module Rufus::Tokyo
33
32
 
34
- #
35
- # The libtokyodystopia.so methods get bound to this module
36
- #
37
- module DystopiaLib #:nodoc#
33
+ #
34
+ # The libtokyodystopia.so methods get bound to this module
35
+ #
36
+ module DystopiaLib #:nodoc#
38
37
 
39
- extend FFI::Library
38
+ extend FFI::Library
40
39
 
41
- #
42
- # find Tokyo Dystopia lib
40
+ #
41
+ # find Tokyo Dystopia lib
43
42
 
44
- paths = Array(ENV['TOKYO_DYSTOPIA_LIB'] || %w{
45
- /opt/local/lib/libtokyodystopia.dylib
46
- /usr/local/lib/libtokyodystopia.dylib
47
- /usr/local/lib/libtokyodystopia.so
48
- })
43
+ paths = Array(ENV['TOKYO_DYSTOPIA_LIB'] || %w{
44
+ /opt/local/lib/libtokyodystopia.dylib
45
+ /usr/local/lib/libtokyodystopia.dylib
46
+ /usr/local/lib/libtokyodystopia.so
47
+ })
49
48
 
50
- if path = paths.find { |path| File.exist?(path) }
49
+ if path = paths.find { |path| File.exist?(path) }
51
50
 
52
- raise "did not find Tokyo Dystopia libs on your system" unless path
51
+ raise "did not find Tokyo Dystopia libs on your system" unless path
53
52
 
54
- ffi_lib(path)
53
+ ffi_lib(path)
55
54
 
56
- #
57
- # tcwdb functions
58
- #
59
- # http://tokyocabinet.sourceforge.net/dystopiadoc/#tcwdbapi
55
+ #
56
+ # tcwdb functions
57
+ #
58
+ # http://tokyocabinet.sourceforge.net/dystopiadoc/#tcwdbapi
60
59
 
61
- attach_function :tcwdbnew, [], :pointer
60
+ attach_function :tcwdbnew, [], :pointer
62
61
 
63
- attach_function :tcwdbopen, [ :pointer, :string, :int ], :int
64
- attach_function :tcwdbclose, [ :pointer ], :int
62
+ attach_function :tcwdbopen, [ :pointer, :string, :int ], :int
63
+ attach_function :tcwdbclose, [ :pointer ], :int
65
64
 
66
- attach_function :tcwdbecode, [ :pointer ], :int
65
+ attach_function :tcwdbecode, [ :pointer ], :int
67
66
 
68
- attach_function :tcwdbput2, [ :pointer, :int64, :string, :string ], :pointer
69
- end
67
+ attach_function :tcwdbput2, [ :pointer, :int64, :string, :string ], :pointer
70
68
  end
71
69
  end
70
+
@@ -28,51 +28,49 @@
28
28
  # jmettraux@gmail.com
29
29
  #
30
30
 
31
- module Rufus
32
- module Tokyo
31
+ module Rufus::Tokyo
32
+
33
+ #
34
+ # Tokyo Dystopia words database.
35
+ #
36
+ # http://tokyocabinet.sourceforge.net/dystopiadoc/
37
+ #
38
+ class Words
33
39
 
34
40
  #
35
- # Tokyo Dystopia words database.
36
- #
37
- # http://tokyocabinet.sourceforge.net/dystopiadoc/
41
+ # TODO : continue me
38
42
  #
39
- class Words
40
43
 
41
- #
42
- # TODO : continue me
43
- #
44
+ #
45
+ # Opens/create a Tokyo Dystopia words database.
46
+ #
47
+ def initialize (path, opts={})
44
48
 
49
+ # tcwdb.h :
45
50
  #
46
- # Opens/create a Tokyo Dystopia words database.
47
- #
48
- def initialize (path, opts={})
51
+ # enum { /* enumeration for open modes */
52
+ # WDBOREADER = 1 << 0, /* open as a reader */
53
+ # WDBOWRITER = 1 << 1, /* open as a writer */
54
+ # WDBOCREAT = 1 << 2, /* writer creating */
55
+ # WDBOTRUNC = 1 << 3, /* writer truncating */
56
+ # WDBONOLCK = 1 << 4, /* open without locking */
57
+ # WDBOLCKNB = 1 << 5 /* lock without blocking */
58
+ # };
49
59
 
50
- # tcwdb.h :
51
- #
52
- # enum { /* enumeration for open modes */
53
- # WDBOREADER = 1 << 0, /* open as a reader */
54
- # WDBOWRITER = 1 << 1, /* open as a writer */
55
- # WDBOCREAT = 1 << 2, /* writer creating */
56
- # WDBOTRUNC = 1 << 3, /* writer truncating */
57
- # WDBONOLCK = 1 << 4, /* open without locking */
58
- # WDBOLCKNB = 1 << 5 /* lock without blocking */
59
- # };
60
+ mode = 0
60
61
 
61
- mode = 0
62
+ @db = dlib.tcwdbnew
62
63
 
63
- @db = dlib.tcwdbnew
64
-
65
- (dlib.tcwdbopen(@db, path, mode) == 1) || raise_error
66
- end
64
+ (dlib.tcwdbopen(@db, path, mode) == 1) || raise_error
65
+ end
67
66
 
68
- protected
67
+ protected
69
68
 
70
- #
71
- # Raises a dystopian error (asks the db which one)
72
- #
73
- def raise_error
74
- raise DystopianError.new(dlib.tcwdbecode(@db))
75
- end
69
+ #
70
+ # Raises a dystopian error (asks the db which one)
71
+ #
72
+ def raise_error
73
+ raise DystopianError.new(dlib.tcwdbecode(@db))
76
74
  end
77
75
  end
78
76
  end
@@ -29,80 +29,81 @@
29
29
  #
30
30
 
31
31
  module Rufus
32
- module Tokyo
32
+ module Tokyo
33
+
34
+ #
35
+ # A mixin for Cabinet and Map, gathers all the hash-like methods
36
+ #
37
+ module HashMethods
38
+ include Enumerable
33
39
 
34
40
  #
35
- # A mixin for Cabinet and Map, gathers all the hash-like methods
41
+ # The [] methods
36
42
  #
37
- module HashMethods
38
- include Enumerable
39
-
40
- #
41
- # The [] methods
42
- #
43
- # (assumes there's an underlying get(k) method)
44
- #
45
- def [] (k)
46
- val = get(k)
47
- return val unless val.nil?
48
- return nil unless @default_proc
49
- @default_proc.call(self, k)
50
- end
51
-
52
- #
53
- # Returns an array of all the values
54
- #
55
- def values
56
- collect { |k, v| v }
57
- end
43
+ # (assumes there's an underlying get(k) method)
44
+ #
45
+ def [] (k)
46
+ val = get(k)
47
+ return val unless val.nil?
48
+ return nil unless @default_proc
49
+ @default_proc.call(self, k)
50
+ end
58
51
 
59
- #
60
- # Our classical 'each'
61
- #
62
- def each
63
- keys.each { |k| yield(k, self[k]) }
64
- end
52
+ #
53
+ # Returns an array of all the values
54
+ #
55
+ def values
56
+ collect { |k, v| v }
57
+ end
65
58
 
66
- #
67
- # Turns this instance into a Ruby hash
68
- #
69
- def to_h
70
- self.inject({}) { |h, (k, v)| h[k] = v; h }
71
- end
59
+ #
60
+ # Our classical 'each'
61
+ #
62
+ def each
63
+ keys.each { |k| yield(k, self[k]) }
64
+ end
72
65
 
73
- #
74
- # Turns this instance into an array of [ key, value ]
75
- #
76
- def to_a
77
- self.collect { |e| e }
78
- end
66
+ #
67
+ # Turns this instance into a Ruby hash
68
+ #
69
+ def to_h
70
+ self.inject({}) { |h, (k, v)| h[k] = v; h }
71
+ end
79
72
 
80
- #
81
- # Returns a new Ruby hash which is a merge of this Map and the given hash
82
- #
83
- def merge (h)
84
- self.to_h.merge(h)
85
- end
73
+ #
74
+ # Turns this instance into an array of [ key, value ]
75
+ #
76
+ def to_a
77
+ self.collect { |e| e }
78
+ end
86
79
 
87
- #
88
- # Merges the entries in the given hash into this map
89
- #
90
- def merge! (h)
91
- h.each { |k, v| self[k] = v }
92
- self
93
- end
80
+ #
81
+ # Returns a new Ruby hash which is a merge of this Map and the given hash
82
+ #
83
+ def merge (h)
84
+ self.to_h.merge(h)
85
+ end
94
86
 
95
- def default (key=nil)
96
- val = self[key]
97
- val.nil? ? @default_proc.call(self, key) : val
98
- end
87
+ #
88
+ # Merges the entries in the given hash into this map
89
+ #
90
+ def merge! (h)
91
+ h.each { |k, v| self[k] = v }
92
+ self
93
+ end
99
94
 
100
- def default= (val)
101
- @default_proc = lambda { |h, k| val }
102
- end
95
+ def default (key=nil)
96
+ val = self[key]
97
+ val.nil? ? @default_proc.call(self, key) : val
98
+ end
103
99
 
104
- attr_reader :default_proc
100
+ def default= (val)
101
+ @default_proc = lambda { |h, k| val }
105
102
  end
106
103
 
104
+ attr_reader :default_proc
107
105
  end
106
+
107
+ end
108
108
  end
109
+