voldemort-rb 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/connection/connection.rb +33 -2
- data/lib/voldemort-rb.rb +28 -5
- data/lib/voldemort-serializer.rb +485 -0
- metadata +10 -4
@@ -10,6 +10,10 @@ class Connection
|
|
10
10
|
attr_accessor :connected_node # The VoldemortNode we are connected to.
|
11
11
|
attr_accessor :request_count # Used to track the number of request a node receives.
|
12
12
|
attr_accessor :request_limit_per_node # Limit the number of request per node.
|
13
|
+
attr_accessor :key_serializer_schemas
|
14
|
+
attr_accessor :value_serializer_schemas
|
15
|
+
attr_accessor :key_serializer_type
|
16
|
+
attr_accessor :value_serializer_type
|
13
17
|
|
14
18
|
STATUS_OK = "ok"
|
15
19
|
PROTOCOL = "pb0"
|
@@ -37,11 +41,16 @@ class Connection
|
|
37
41
|
stores_response = self.get_from("metadata", "stores.xml", false)
|
38
42
|
stores_xml = stores_response[1][0][1]
|
39
43
|
|
44
|
+
self.key_serializer_type = parse_schema_type(stores_xml, 'key-serializer')
|
45
|
+
self.value_serializer_type = parse_schema_type(stores_xml, 'value-serializer')
|
46
|
+
self.key_serializer_schemas = parse_schema_from(stores_xml, 'key-serializer')
|
47
|
+
self.value_serializer_schemas = parse_schema_from(stores_xml, 'value-serializer')
|
48
|
+
|
40
49
|
self.connect_to_random_node
|
41
50
|
rescue StandardError => e
|
42
|
-
|
51
|
+
raise("There was an error trying to bootstrap from the specified servers: #{e}")
|
43
52
|
end
|
44
|
-
|
53
|
+
|
45
54
|
def connect_to_random_node
|
46
55
|
nodes = self.nodes.sort_by { rand }
|
47
56
|
for node in nodes do
|
@@ -52,6 +61,28 @@ class Connection
|
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
64
|
+
|
65
|
+
def parse_schema_type(xml, serializer = 'value-serializer')
|
66
|
+
doc = REXML::Document.new(xml)
|
67
|
+
type_doc = XPath.first(doc, "//stores/store[name = \"#{self.db_name}\"]/#{serializer}/type")
|
68
|
+
|
69
|
+
if(type_doc != nil)
|
70
|
+
return type_doc.text
|
71
|
+
else
|
72
|
+
return nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_schema_from(xml, serializer = 'value-serializer')
|
77
|
+
parsed_schemas = {}
|
78
|
+
doc = REXML::Document.new(xml)
|
79
|
+
|
80
|
+
XPath.each(doc, "//stores/store[name = \"#{self.db_name}\"]/#{serializer}/schema-info") do |value_serializer|
|
81
|
+
parsed_schemas[value_serializer.attributes['version']] = value_serializer.text
|
82
|
+
end
|
83
|
+
|
84
|
+
return parsed_schemas
|
85
|
+
end
|
55
86
|
|
56
87
|
def parse_nodes_from(xml)
|
57
88
|
nodes = []
|
data/lib/voldemort-rb.rb
CHANGED
@@ -1,42 +1,65 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "connection", "voldemort_node")
|
2
2
|
require File.join(File.dirname(__FILE__), "connection", "connection")
|
3
3
|
require File.join(File.dirname(__FILE__), "connection", "tcp_connection")
|
4
|
+
require File.join(File.dirname(__FILE__), "voldemort-serializer")
|
4
5
|
|
5
6
|
class VoldemortClient
|
6
7
|
attr_accessor :connection
|
7
8
|
attr_accessor :conflict_resolver
|
9
|
+
attr_accessor :key_serializer
|
10
|
+
attr_accessor :value_serializer
|
8
11
|
|
9
12
|
def initialize(db_name, *hosts, &block)
|
10
13
|
self.conflict_resolver = block unless !block
|
11
14
|
self.connection = TCPConnection.new(db_name, hosts) # implement and modifiy if you don't want to use TCP protobuf.
|
12
15
|
self.connection.bootstrap
|
16
|
+
|
17
|
+
case(self.connection.key_serializer_type)
|
18
|
+
when 'json'
|
19
|
+
self.key_serializer = VoldemortJsonBinarySerializer.new(self.connection.key_serializer_schemas)
|
20
|
+
else
|
21
|
+
self.key_serializer = VoldemortPassThroughSerializer.new({})
|
22
|
+
end
|
23
|
+
|
24
|
+
case(self.connection.value_serializer_type)
|
25
|
+
when 'json'
|
26
|
+
self.value_serializer = VoldemortJsonBinarySerializer.new(self.connection.value_serializer_schemas)
|
27
|
+
else
|
28
|
+
self.value_serializer = VoldemortPassThroughSerializer.new({})
|
29
|
+
end
|
13
30
|
end
|
14
31
|
|
15
32
|
def get(key)
|
16
|
-
versions = self.connection.get(key)
|
33
|
+
versions = self.connection.get(key_serializer.to_bytes(key))
|
17
34
|
version = self.resolve_conflicts(versions.versioned)
|
18
35
|
if version
|
19
|
-
version.value
|
36
|
+
value_serializer.to_object(version.value)
|
20
37
|
else
|
21
38
|
nil
|
22
39
|
end
|
23
40
|
end
|
24
41
|
|
25
42
|
def get_all(keys)
|
43
|
+
serialized_keys = []
|
44
|
+
|
45
|
+
keys.each do |key|
|
46
|
+
serialized_keys << key_serializer.to_bytes(key)
|
47
|
+
end
|
48
|
+
|
26
49
|
all_version = self.connection.get_all(keys)
|
27
50
|
values = {}
|
28
51
|
all_version.values.collect do |v|
|
29
|
-
values[v.key] = self.resolve_conflicts(v.versions).value
|
52
|
+
values[v.key] = value_serializer.to_object(self.resolve_conflicts(v.versions).value)
|
30
53
|
end
|
31
54
|
values
|
32
55
|
end
|
33
56
|
|
34
57
|
def put(key, value, version = nil)
|
35
|
-
self.connection.put(key, value)
|
58
|
+
self.connection.put(key_serializer.to_bytes(key), value_serializer.to_bytes(value))
|
36
59
|
end
|
37
60
|
|
38
61
|
def delete(key)
|
39
|
-
self.connection.delete(key)
|
62
|
+
self.connection.delete(key_serializer.to_bytes(key))
|
40
63
|
end
|
41
64
|
|
42
65
|
def resolve_conflicts(versions)
|
@@ -0,0 +1,485 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'voldemort-rb'
|
3
|
+
|
4
|
+
class VoldemortJsonBinarySerializer
|
5
|
+
attr_accessor :has_version
|
6
|
+
attr_accessor :type_def_versions
|
7
|
+
|
8
|
+
BYTE_MIN_VAL = -128
|
9
|
+
SHORT_MIN_VAL = -32768
|
10
|
+
SHORT_MAX_VAL = 2 ** 15 - 1
|
11
|
+
INT_MIN_VAL = -2147483648
|
12
|
+
LONG_MIN_VAL = -9223372036854775808
|
13
|
+
FLOAT_MIN_VAL = 2 ** -149
|
14
|
+
DOUBLE_MIN_VAL = 2 ** -1074
|
15
|
+
|
16
|
+
def initialize(type_def_versions)
|
17
|
+
@has_version = true
|
18
|
+
@type_def_versions = {}
|
19
|
+
|
20
|
+
# convert versioned json strings to ruby objects
|
21
|
+
type_def_versions.each_pair do |version, json_type_def_version|
|
22
|
+
@type_def_versions[version.to_i] = get_type_def(json_type_def_version)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_signed(unsigned, bits)
|
27
|
+
max_unsigned = 2 ** bits
|
28
|
+
max_signed = 2 ** (bits - 1)
|
29
|
+
to_signed = proc { |n| (n >= max_signed) ? n - max_unsigned : n }
|
30
|
+
return to_signed[unsigned]
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_type_def(json_type_def_version)
|
34
|
+
# replace all single quotes with " since the JSON parser wants it this way
|
35
|
+
json_type_def_version = json_type_def_version.gsub(/\'/, '"')
|
36
|
+
|
37
|
+
if((json_type_def_version =~ /[\{\[]/) == 0)
|
38
|
+
# check if the json is a list or string, since these are
|
39
|
+
# the only ones that JSON.parse() will work with
|
40
|
+
return JSON.parse(json_type_def_version)
|
41
|
+
else
|
42
|
+
# otherwise it's a primitive, so just strip the quotes
|
43
|
+
return json_type_def_version.gsub(/\"/, '')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def read_slice(length, bytes)
|
48
|
+
substr = bytes[0, length]
|
49
|
+
bytes.slice!(0..length - 1)
|
50
|
+
return substr
|
51
|
+
end
|
52
|
+
|
53
|
+
# handle serialization
|
54
|
+
|
55
|
+
def to_bytes(object)
|
56
|
+
bytes = ''
|
57
|
+
newest_version = 0 # TODO get highest number from map
|
58
|
+
type_def = @type_def_versions[newest_version]
|
59
|
+
|
60
|
+
if(@has_version)
|
61
|
+
bytes << newest_version.chr
|
62
|
+
end
|
63
|
+
|
64
|
+
bytes << write(object, type_def)
|
65
|
+
|
66
|
+
return bytes
|
67
|
+
end
|
68
|
+
|
69
|
+
def write(object, type)
|
70
|
+
bytes = ''
|
71
|
+
|
72
|
+
if(type.kind_of? Hash)
|
73
|
+
if(object != nil && !object.kind_of?(Hash))
|
74
|
+
# TODO throw exception
|
75
|
+
else
|
76
|
+
bytes << write_map(object, type)
|
77
|
+
end
|
78
|
+
elsif(type.kind_of? Array)
|
79
|
+
if(object != nil && !object.kind_of?(Array))
|
80
|
+
# TODO throw exception
|
81
|
+
else
|
82
|
+
bytes << write_list(object, type)
|
83
|
+
end
|
84
|
+
else
|
85
|
+
case(type)
|
86
|
+
when 'string': bytes << write_string(object)
|
87
|
+
when 'int8': bytes << write_int8(object)
|
88
|
+
when 'int16': bytes << write_int16(object)
|
89
|
+
when 'int32': bytes << write_int32(object)
|
90
|
+
when 'int64': bytes << write_int64(object)
|
91
|
+
when 'float32': bytes << write_float32(object)
|
92
|
+
when 'float64': bytes << write_float64(object)
|
93
|
+
when 'date': bytes << write_date(object)
|
94
|
+
when 'bytes': bytes << write_bytes(object)
|
95
|
+
when 'boolean': bytes << write_boolean(object)
|
96
|
+
else
|
97
|
+
# TODO throw unsupported type exception
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
if(bytes == '')
|
102
|
+
return nil
|
103
|
+
end
|
104
|
+
|
105
|
+
return bytes
|
106
|
+
end
|
107
|
+
|
108
|
+
def write_boolean(object)
|
109
|
+
bytes = ''
|
110
|
+
|
111
|
+
if(object == nil)
|
112
|
+
bytes << [BYTE_MIN_VAL].pack('c')
|
113
|
+
elsif(object)
|
114
|
+
bytes << [0x1].pack('c')
|
115
|
+
else
|
116
|
+
bytes << [0x0].pack('c')
|
117
|
+
end
|
118
|
+
|
119
|
+
return bytes
|
120
|
+
end
|
121
|
+
|
122
|
+
def write_string(object)
|
123
|
+
return write_bytes(object)
|
124
|
+
end
|
125
|
+
|
126
|
+
def write_int8(object)
|
127
|
+
bytes = ''
|
128
|
+
|
129
|
+
if(object == BYTE_MIN_VAL)
|
130
|
+
# TODO throw underflow exception
|
131
|
+
else
|
132
|
+
if(object == nil)
|
133
|
+
object = BYTE_MIN_VAL
|
134
|
+
end
|
135
|
+
|
136
|
+
bytes << [object].pack('c')
|
137
|
+
end
|
138
|
+
|
139
|
+
return bytes
|
140
|
+
end
|
141
|
+
|
142
|
+
def write_int16(object)
|
143
|
+
bytes = ''
|
144
|
+
|
145
|
+
if(object == SHORT_MIN_VAL)
|
146
|
+
# TODO throw underflow exception
|
147
|
+
else
|
148
|
+
if(object == nil)
|
149
|
+
object = SHORT_MIN_VAL
|
150
|
+
end
|
151
|
+
|
152
|
+
bytes << [object].pack('n')
|
153
|
+
end
|
154
|
+
|
155
|
+
return bytes
|
156
|
+
end
|
157
|
+
|
158
|
+
def write_int32(object)
|
159
|
+
bytes = ''
|
160
|
+
|
161
|
+
if(object == INT_MIN_VAL)
|
162
|
+
# TODO throw underflow exception
|
163
|
+
else
|
164
|
+
if(object == nil)
|
165
|
+
object = INT_MIN_VAL
|
166
|
+
end
|
167
|
+
|
168
|
+
# reverse here to switch little endian to big endian
|
169
|
+
# this is because pack('N') is choking on 'bigint', wtf?
|
170
|
+
bytes << [object].pack('i').reverse
|
171
|
+
end
|
172
|
+
|
173
|
+
return bytes
|
174
|
+
end
|
175
|
+
|
176
|
+
def write_int64(object)
|
177
|
+
bytes = ''
|
178
|
+
|
179
|
+
if(object == LONG_MIN_VAL)
|
180
|
+
# TODO throw underflow exception
|
181
|
+
else
|
182
|
+
if(object == nil)
|
183
|
+
object = LONG_MIN_VAL
|
184
|
+
end
|
185
|
+
|
186
|
+
# reverse here to switch little endian to big endian
|
187
|
+
# this is because pack('N') is choking on 'bigint', wtf?
|
188
|
+
bytes << [object].pack('q').reverse
|
189
|
+
end
|
190
|
+
|
191
|
+
return bytes
|
192
|
+
end
|
193
|
+
|
194
|
+
def write_float32(object)
|
195
|
+
bytes = ''
|
196
|
+
|
197
|
+
if(object == FLOAT_MIN_VAL)
|
198
|
+
# TODO throw underflow exception
|
199
|
+
else
|
200
|
+
if(object == nil)
|
201
|
+
object = FLOAT_MIN_VAL
|
202
|
+
end
|
203
|
+
|
204
|
+
bytes << [object].pack('g')
|
205
|
+
end
|
206
|
+
|
207
|
+
return bytes
|
208
|
+
end
|
209
|
+
|
210
|
+
def write_float64(object)
|
211
|
+
bytes = ''
|
212
|
+
|
213
|
+
if(object == DOUBLE_MIN_VAL)
|
214
|
+
# TODO throw underflow exception
|
215
|
+
else
|
216
|
+
if(object == nil)
|
217
|
+
object = DOUBLE_MIN_VAL
|
218
|
+
end
|
219
|
+
|
220
|
+
bytes << [object].pack('G')
|
221
|
+
end
|
222
|
+
|
223
|
+
return bytes
|
224
|
+
end
|
225
|
+
|
226
|
+
def write_date(object)
|
227
|
+
bytes = ''
|
228
|
+
|
229
|
+
if(object == LONG_MIN_VAL)
|
230
|
+
# TODO throw underflow exception
|
231
|
+
else
|
232
|
+
if(object == nil)
|
233
|
+
bytes << write_int64(nil)
|
234
|
+
else
|
235
|
+
bytes << write_int64((object.to_f * 1000).to_i)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
return bytes
|
240
|
+
end
|
241
|
+
|
242
|
+
def write_bytes(object)
|
243
|
+
bytes = ''
|
244
|
+
|
245
|
+
if(object == nil)
|
246
|
+
bytes << write_int16(-1)
|
247
|
+
elsif(object.length < SHORT_MAX_VAL)
|
248
|
+
bytes << write_int16(object.length)
|
249
|
+
bytes << object
|
250
|
+
else
|
251
|
+
# TODO throw "length too long to serialize" exception
|
252
|
+
end
|
253
|
+
|
254
|
+
return bytes
|
255
|
+
end
|
256
|
+
|
257
|
+
def write_map(object, type)
|
258
|
+
bytes = ''
|
259
|
+
|
260
|
+
if(object == nil)
|
261
|
+
bytes << [-1].pack('c')
|
262
|
+
else
|
263
|
+
bytes << [1].pack('c')
|
264
|
+
|
265
|
+
if(object.length != type.length)
|
266
|
+
# TODO throw exception here.. invalid map serialization, expected: but got
|
267
|
+
else
|
268
|
+
type.sort.each do |type_pair|
|
269
|
+
key = type_pair.first
|
270
|
+
subtype = type_pair.last
|
271
|
+
|
272
|
+
if(!object.has_key? key)
|
273
|
+
# TODO throw "missing property exception"
|
274
|
+
else
|
275
|
+
bytes << write(object[key], subtype)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
return bytes
|
282
|
+
end
|
283
|
+
|
284
|
+
def write_list(object, type)
|
285
|
+
bytes = ''
|
286
|
+
|
287
|
+
if(type.length != 1)
|
288
|
+
# TODO throw new exception (expected single type in list)
|
289
|
+
else
|
290
|
+
entry_type = type.first
|
291
|
+
|
292
|
+
if(object == nil)
|
293
|
+
bytes << write_int16(-1)
|
294
|
+
elsif(object.length < SHORT_MAX_VAL)
|
295
|
+
bytes << write_int16(object.length)
|
296
|
+
object.each do |o|
|
297
|
+
bytes << write(o, entry_type)
|
298
|
+
end
|
299
|
+
else
|
300
|
+
# TODO throw serialization exception
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
return bytes
|
305
|
+
end
|
306
|
+
|
307
|
+
# handle deserialization
|
308
|
+
|
309
|
+
def to_object(bytes)
|
310
|
+
version = 0
|
311
|
+
|
312
|
+
if(@has_version)
|
313
|
+
version = read_slice(1, bytes).to_i
|
314
|
+
end
|
315
|
+
|
316
|
+
type = @type_def_versions[version]
|
317
|
+
|
318
|
+
if(type == nil)
|
319
|
+
# TODO throw exception here
|
320
|
+
end
|
321
|
+
|
322
|
+
return read(bytes, type)
|
323
|
+
end
|
324
|
+
|
325
|
+
def read(bytes, type)
|
326
|
+
if(type.kind_of? Hash)
|
327
|
+
return read_map(bytes, type)
|
328
|
+
elsif(type.kind_of? Array)
|
329
|
+
return read_list(bytes, type)
|
330
|
+
else
|
331
|
+
case(type)
|
332
|
+
when 'string': return read_bytes(bytes)
|
333
|
+
when 'int8': return read_int8(bytes)
|
334
|
+
when 'int16': return read_int16(bytes)
|
335
|
+
when 'int32': return read_int32(bytes)
|
336
|
+
when 'int64': return read_int64(bytes)
|
337
|
+
when 'float32': return read_float32(bytes)
|
338
|
+
when 'float64': return read_float64(bytes)
|
339
|
+
when 'date': return read_date(bytes)
|
340
|
+
when 'bytes': return read_bytes(bytes)
|
341
|
+
when 'boolean': return read_boolean(bytes)
|
342
|
+
# TODO default throw unknown type exception
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def read_map(bytes, type)
|
348
|
+
# convert to char to string, and string to int
|
349
|
+
if(read_slice(1, bytes).unpack('c').to_s.to_i == -1)
|
350
|
+
return nil
|
351
|
+
else
|
352
|
+
object = {}
|
353
|
+
|
354
|
+
type.sort.each do |type_pair|
|
355
|
+
name = type_pair.first
|
356
|
+
sub_type = type_pair.last
|
357
|
+
object[name] = read(bytes, sub_type)
|
358
|
+
end
|
359
|
+
|
360
|
+
return object
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def read_list(bytes, type)
|
365
|
+
size = read_int16(bytes)
|
366
|
+
if(size < 0)
|
367
|
+
return nil
|
368
|
+
else
|
369
|
+
object = []
|
370
|
+
|
371
|
+
size.times { object << read(bytes, type.first) }
|
372
|
+
|
373
|
+
return object
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def read_boolean(bytes)
|
378
|
+
b = read_slice(1, bytes).unpack('c').first
|
379
|
+
|
380
|
+
if(b < 0)
|
381
|
+
return nil
|
382
|
+
elsif(b == 0)
|
383
|
+
return false
|
384
|
+
else
|
385
|
+
return true
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def read_int8(bytes)
|
390
|
+
b = read_slice(1, bytes).unpack("c").first.to_i
|
391
|
+
|
392
|
+
if(b == BYTE_MIN_VAL)
|
393
|
+
return nil
|
394
|
+
end
|
395
|
+
|
396
|
+
return b
|
397
|
+
end
|
398
|
+
|
399
|
+
def read_int16(bytes)
|
400
|
+
s = to_signed(read_slice(2, bytes).unpack("n").first, 16)
|
401
|
+
|
402
|
+
if(s == SHORT_MIN_VAL)
|
403
|
+
return nil
|
404
|
+
end
|
405
|
+
|
406
|
+
return s
|
407
|
+
end
|
408
|
+
|
409
|
+
def read_int32(bytes)
|
410
|
+
# reverse here to switch little endian to big endian
|
411
|
+
# this is because pack('N') is choking on 'bigint', wtf?
|
412
|
+
i = read_slice(4, bytes).reverse.unpack("i").first.to_i
|
413
|
+
|
414
|
+
if(i == INT_MIN_VAL)
|
415
|
+
return nil
|
416
|
+
end
|
417
|
+
|
418
|
+
return i
|
419
|
+
end
|
420
|
+
|
421
|
+
def read_int64(bytes)
|
422
|
+
# reverse here to switch little endian to big endian
|
423
|
+
# this is because pack('N') is choking on 'bigint', wtf?
|
424
|
+
l = read_slice(8, bytes).reverse.unpack("q").first.to_i
|
425
|
+
|
426
|
+
if(l == LONG_MIN_VAL)
|
427
|
+
return nil
|
428
|
+
end
|
429
|
+
|
430
|
+
return l
|
431
|
+
end
|
432
|
+
|
433
|
+
def read_float32(bytes)
|
434
|
+
f = read_slice(4, bytes).unpack("g").first.to_f
|
435
|
+
|
436
|
+
if(f == FLOAT_MIN_VAL)
|
437
|
+
return nil
|
438
|
+
end
|
439
|
+
|
440
|
+
return f
|
441
|
+
end
|
442
|
+
|
443
|
+
def read_float64(bytes)
|
444
|
+
d = read_slice(8, bytes).unpack("G").first.to_f
|
445
|
+
|
446
|
+
if(d == DOUBLE_MIN_VAL)
|
447
|
+
return nil
|
448
|
+
end
|
449
|
+
|
450
|
+
return d
|
451
|
+
end
|
452
|
+
|
453
|
+
def read_date(bytes)
|
454
|
+
d = read_int64(bytes)
|
455
|
+
|
456
|
+
if(d != nil)
|
457
|
+
d = Time.at((d / 1000).to_i, d % 1000)
|
458
|
+
end
|
459
|
+
|
460
|
+
return d
|
461
|
+
end
|
462
|
+
|
463
|
+
def read_bytes(bytes)
|
464
|
+
size = read_int16(bytes)
|
465
|
+
|
466
|
+
if(size < 0)
|
467
|
+
return nil
|
468
|
+
else
|
469
|
+
return read_slice(size, bytes)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
class VoldemortPassThroughSerializer
|
475
|
+
def initialize(map)
|
476
|
+
end
|
477
|
+
|
478
|
+
def to_bytes(bytes)
|
479
|
+
bytes
|
480
|
+
end
|
481
|
+
|
482
|
+
def to_object(object)
|
483
|
+
object
|
484
|
+
end
|
485
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: voldemort-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Alejandro Crosa
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-09-13 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|
@@ -33,6 +34,7 @@ files:
|
|
33
34
|
- README.md
|
34
35
|
- Rakefile
|
35
36
|
- lib/voldemort-rb.rb
|
37
|
+
- lib/voldemort-serializer.rb
|
36
38
|
- lib/connection/connection.rb
|
37
39
|
- lib/connection/tcp_connection.rb
|
38
40
|
- lib/connection/voldemort_node.rb
|
@@ -53,23 +55,27 @@ rdoc_options: []
|
|
53
55
|
require_paths:
|
54
56
|
- lib
|
55
57
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
56
59
|
requirements:
|
57
60
|
- - ">="
|
58
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
59
63
|
segments:
|
60
64
|
- 0
|
61
65
|
version: "0"
|
62
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
63
68
|
requirements:
|
64
69
|
- - ">="
|
65
70
|
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
66
72
|
segments:
|
67
73
|
- 0
|
68
74
|
version: "0"
|
69
75
|
requirements: []
|
70
76
|
|
71
77
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.3.
|
78
|
+
rubygems_version: 1.3.7
|
73
79
|
signing_key:
|
74
80
|
specification_version: 3
|
75
81
|
summary: A Ruby client for the Voldemort distributed key value store
|