tarantool 0.3.0.7 → 0.4.2.1
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/Gemfile +2 -3
- data/README.md +90 -30
- data/Rakefile +6 -1
- data/lib/tarantool.rb +93 -18
- data/lib/tarantool/base_record.rb +97 -10
- data/lib/tarantool/block_db.rb +104 -6
- data/lib/tarantool/callback_db.rb +7 -0
- data/lib/tarantool/core-ext.rb +24 -8
- data/lib/tarantool/em_db.rb +189 -20
- data/lib/tarantool/exceptions.rb +4 -0
- data/lib/tarantool/fiber_db.rb +15 -1
- data/lib/tarantool/light_record.rb +17 -0
- data/lib/tarantool/query.rb +15 -9
- data/lib/tarantool/record/select.rb +21 -3
- data/lib/tarantool/request.rb +130 -43
- data/lib/tarantool/response.rb +70 -7
- data/lib/tarantool/serializers.rb +26 -5
- data/lib/tarantool/serializers/ber_array.rb +14 -0
- data/lib/tarantool/shards_support.rb +204 -0
- data/lib/tarantool/space_array.rb +38 -13
- data/lib/tarantool/space_hash.rb +49 -27
- data/lib/tarantool/util.rb +96 -10
- data/lib/tarantool/version.rb +2 -1
- data/test/helper.rb +154 -4
- data/test/{tarant/init.lua → init.lua} +0 -0
- data/test/run_all.rb +2 -2
- data/test/shared_record.rb +59 -0
- data/test/shared_replicated_shard.rb +1018 -0
- data/test/shared_reshard.rb +380 -0
- data/test/tarantool.cfg +2 -0
- data/test/test_light_record.rb +2 -0
- data/test/test_light_record_callback.rb +92 -0
- data/test/test_query_block.rb +1 -0
- data/test/test_query_fiber.rb +1 -0
- data/test/test_reshard_block.rb +7 -0
- data/test/test_reshard_fiber.rb +11 -0
- data/test/test_shard_replication_block.rb +7 -0
- data/test/test_shard_replication_fiber.rb +11 -0
- data/test/test_space_array_block.rb +1 -0
- data/test/test_space_array_callback.rb +50 -121
- data/test/test_space_array_callback_nodef.rb +39 -96
- data/test/test_space_array_fiber.rb +1 -0
- data/test/test_space_hash_block.rb +1 -0
- data/test/test_space_hash_fiber.rb +1 -0
- metadata +54 -17
- data/lib/tarantool/record.rb +0 -164
- data/test/box.pid +0 -1
- data/test/tarantool.log +0 -6
- data/test/tarantool_repl.cfg +0 -53
- data/test/test_record.rb +0 -88
- data/test/test_record_composite_pk.rb +0 -77
data/lib/tarantool/response.rb
CHANGED
@@ -3,16 +3,32 @@ require 'tarantool/exceptions'
|
|
3
3
|
require 'tarantool/serializers'
|
4
4
|
|
5
5
|
module Tarantool
|
6
|
-
|
6
|
+
module ParseIProto
|
7
|
+
include Util::Packer
|
8
|
+
def _parse_iproto(data)
|
9
|
+
if Exception === data || data == ''
|
10
|
+
data
|
11
|
+
elsif (ret = unpack_int32!(data)) == 0
|
12
|
+
data
|
13
|
+
else
|
14
|
+
data.gsub!("\x00", "")
|
15
|
+
CODE_TO_EXCEPTION[ret].new(ret, data)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Response < Struct.new(:cb, :request_type, :body, :get_tuples, :fields, :translators)
|
7
21
|
include Util::Packer
|
8
22
|
include Util::TailGetter
|
9
23
|
include Serializers
|
24
|
+
UTF8 = 'utf-8'.freeze
|
25
|
+
|
10
26
|
def call(data)
|
11
27
|
if Exception === data
|
12
28
|
cb.call(data)
|
13
29
|
else
|
14
30
|
if (ret = return_code(data)) == 0
|
15
|
-
|
31
|
+
call_callback parse_response(data)
|
16
32
|
else
|
17
33
|
data.gsub!("\x00", "")
|
18
34
|
cb.call CODE_TO_EXCEPTION[ret].new(ret, data)
|
@@ -24,7 +40,12 @@ module Tarantool
|
|
24
40
|
super || (self.translators = [])
|
25
41
|
end
|
26
42
|
|
43
|
+
def call_callback(result)
|
44
|
+
cb.call(Exception === result || get_tuples != :first ? result : result.first)
|
45
|
+
end
|
46
|
+
|
27
47
|
def parse_response(data)
|
48
|
+
return data if Exception === data
|
28
49
|
unless get_tuples
|
29
50
|
unpack_int32(data)
|
30
51
|
else
|
@@ -34,7 +55,7 @@ module Tarantool
|
|
34
55
|
tuples.map!{|tuple| trans.call(tuple)}
|
35
56
|
}
|
36
57
|
end
|
37
|
-
|
58
|
+
tuples
|
38
59
|
end
|
39
60
|
end
|
40
61
|
|
@@ -62,6 +83,52 @@ module Tarantool
|
|
62
83
|
tuple << (field_size == 0 ? nil :
|
63
84
|
case field
|
64
85
|
when :int, :integer
|
86
|
+
if field_size != 4
|
87
|
+
raise ValueError, "Bad field size #{field_size} for integer field ##{i}"
|
88
|
+
end
|
89
|
+
unpack_int32!(tuple_str)
|
90
|
+
when :string, :str
|
91
|
+
str = tuple_str.slice!(0, field_size)
|
92
|
+
str[0,1] = EMPTY if str < ONE
|
93
|
+
str.force_encoding(UTF8)
|
94
|
+
when :int64
|
95
|
+
if field_size != 8
|
96
|
+
raise ValueError, "Bad field size #{field_size} for 64bit integer field ##{i}"
|
97
|
+
end
|
98
|
+
unpack_int64!(tuple_str)
|
99
|
+
when :bytes
|
100
|
+
tuple_str.slice!(0, field_size)
|
101
|
+
when :int16
|
102
|
+
if field_size != 2
|
103
|
+
raise ValueError, "Bad field size #{field_size} for 16bit integer field ##{i}"
|
104
|
+
end
|
105
|
+
unpack_int16!(tuple_str)
|
106
|
+
when :int8
|
107
|
+
if field_size != 1
|
108
|
+
raise ValueError, "Bad field size #{field_size} for 8bit integer field ##{i}"
|
109
|
+
end
|
110
|
+
unpack_int8!(tuple_str)
|
111
|
+
when :sint
|
112
|
+
if field_size != 4
|
113
|
+
raise ValueError, "Bad field size #{field_size} for integer field ##{i}"
|
114
|
+
end
|
115
|
+
unpack_sint32!(tuple_str)
|
116
|
+
when :sint64
|
117
|
+
if field_size != 8
|
118
|
+
raise ValueError, "Bad field size #{field_size} for 64bit integer field ##{i}"
|
119
|
+
end
|
120
|
+
unpack_sint64!(tuple_str)
|
121
|
+
when :sint16
|
122
|
+
if field_size != 2
|
123
|
+
raise ValueError, "Bad field size #{field_size} for 16bit integer field ##{i}"
|
124
|
+
end
|
125
|
+
unpack_sint16!(tuple_str)
|
126
|
+
when :sint8
|
127
|
+
if field_size != 1
|
128
|
+
raise ValueError, "Bad field size #{field_size} for 8bit integer field ##{i}"
|
129
|
+
end
|
130
|
+
unpack_sint8!(tuple_str)
|
131
|
+
when :varint
|
65
132
|
case field_size
|
66
133
|
when 8
|
67
134
|
unpack_int64!(tuple_str)
|
@@ -72,10 +139,6 @@ module Tarantool
|
|
72
139
|
else
|
73
140
|
raise ValueError, "Bad field size #{field_size} for integer field ##{i}"
|
74
141
|
end
|
75
|
-
when :str, :string
|
76
|
-
tuple_str.slice!(0, field_size).force_encoding('utf-8')
|
77
|
-
when :bytes
|
78
|
-
tuple_str.slice!(0, field_size)
|
79
142
|
when :auto
|
80
143
|
str = tuple_str.slice!(0, field_size).force_encoding('utf-8')
|
81
144
|
case field_size
|
@@ -4,22 +4,43 @@ module Tarantool
|
|
4
4
|
|
5
5
|
def check_type(type)
|
6
6
|
type = type.to_sym if String === type
|
7
|
-
return :
|
8
|
-
return :
|
7
|
+
return :varint if Integer == type
|
8
|
+
return :string if String == type
|
9
9
|
|
10
10
|
case type
|
11
|
-
when :int, :integer, :
|
12
|
-
|
11
|
+
when :int, :integer, :int32, :integer32
|
12
|
+
:int
|
13
|
+
when :int64, :integer64
|
14
|
+
:int64
|
15
|
+
when :int16, :integer16
|
16
|
+
:int16
|
17
|
+
when :int8, :integer8
|
18
|
+
:int8
|
19
|
+
when :sint, :sinteger, :sint32, :sinteger32
|
20
|
+
:sint
|
21
|
+
when :sint16, :sinteger16
|
22
|
+
:sint16
|
23
|
+
when :sint64, :sinteger64
|
24
|
+
:sint64
|
25
|
+
when :sint8, :sinteger8
|
26
|
+
:sint8
|
27
|
+
when :varint
|
28
|
+
:varint
|
29
|
+
when :str, :string
|
30
|
+
:string
|
31
|
+
when :bytes, :auto
|
32
|
+
type
|
13
33
|
when Symbol
|
14
34
|
unless MAP.include?(type)
|
15
35
|
raise ArgumentError, "Unknown type name #{type.inspect}"
|
16
36
|
end
|
37
|
+
type
|
17
38
|
else
|
18
39
|
unless type.respond_to?(:encode) && type.respond_to?(:decode)
|
19
40
|
raise ArgumentError, "Wrong serializer object #{type.inspect} (must respond to #encode and #decode)"
|
20
41
|
end
|
42
|
+
type
|
21
43
|
end
|
22
|
-
type
|
23
44
|
end
|
24
45
|
|
25
46
|
def get_serializer(type)
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'sumbur'
|
2
|
+
require 'murmurhash3'
|
3
|
+
module Tarantool
|
4
|
+
module Request
|
5
|
+
class SumburMurmur32
|
6
|
+
include Sumbur
|
7
|
+
include MurmurHash3::V32
|
8
|
+
end
|
9
|
+
|
10
|
+
class SumburMurmurFmix < SumburMurmur32
|
11
|
+
def call(shard_values, shards_count, this)
|
12
|
+
shard_values[0] &&
|
13
|
+
sumbur(murmur3_32_fmix(shard_values[0]), shards_count)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SumburMurmurInt64 < SumburMurmur32
|
18
|
+
def call(shard_values, shards_count, this)
|
19
|
+
shard_values[0] &&
|
20
|
+
sumbur(murmur3_32_int64_hash(shard_values[0]), shards_count)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class SumburMurmurStr < SumburMurmur32
|
25
|
+
def call(shard_values, shards_count, this)
|
26
|
+
shard_values[0] &&
|
27
|
+
sumbur(murmur3_32_str_hash(shard_values[0]), shards_count)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class DefaultShardProc < SumburMurmur32
|
32
|
+
def call(shard_values, shards_count, this)
|
33
|
+
if shard_values.all?
|
34
|
+
hash = i = 0
|
35
|
+
size = shard_values.size
|
36
|
+
while i < size
|
37
|
+
hash = case value = shard_values[i]
|
38
|
+
when Integer
|
39
|
+
murmur3_32_int64_hash(value, hash)
|
40
|
+
when String
|
41
|
+
murmur3_32_str_hash(value, hash)
|
42
|
+
else
|
43
|
+
raise ValueError, "Default sharding proc could deal only with strings and integers"
|
44
|
+
end
|
45
|
+
i += 1
|
46
|
+
end
|
47
|
+
sumbur(hash, shards_count)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class ModuloShardProc
|
53
|
+
def call(shard_values, shards_count, this)
|
54
|
+
shard_values[0] && shard_values[0] % shards_count
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :shard_proc, :shards_count, :previous_shards_count
|
59
|
+
attr_reader :insert_with_shards_count
|
60
|
+
|
61
|
+
def _init_shard_vars(shard_proc, init_shard_for_index = true)
|
62
|
+
if init_shard_for_index
|
63
|
+
@shard_by_index = @index_fields.index{|index| index == @shard_fields}
|
64
|
+
@shard_for_index = @index_fields.map{|index|
|
65
|
+
if (pos = @shard_fields.map{|name| index.index(name)}).any?
|
66
|
+
pos.map{|i| i || 2**30}
|
67
|
+
end
|
68
|
+
}
|
69
|
+
@shard_proc = case shard_proc
|
70
|
+
when nil, :default
|
71
|
+
DefaultShardProc.new
|
72
|
+
when :sumbur_murmur_fmix
|
73
|
+
SumburMurmurFmix.new
|
74
|
+
when :sumbur_murmur_int64
|
75
|
+
SumburMurmurInt64.new
|
76
|
+
when :sumbur_murmur_str
|
77
|
+
SumburMurmurStr.new
|
78
|
+
when :modulo, :module
|
79
|
+
ModuloShardProc.new
|
80
|
+
else
|
81
|
+
unless shard_proc.respond_to?(:call)
|
82
|
+
raise ArgumentError, "Wrong sharding proc object #{shard_proc.inspect}"
|
83
|
+
end
|
84
|
+
shard_proc
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
@shards_count = @tarantool.shards_count
|
89
|
+
@previous_shards_count = @tarantool.previous_shards_count
|
90
|
+
@insert_with_shards_count = @tarantool.insert_with_shards_count
|
91
|
+
@default_shard = 0
|
92
|
+
end
|
93
|
+
|
94
|
+
def _detect_shards_for_keys(keys, index_no)
|
95
|
+
return _detect_shards_for_key(keys, index_no) unless Array === keys
|
96
|
+
if index_no == @shard_by_index && (
|
97
|
+
@index_fields.size == 1 ||
|
98
|
+
keys.all?{|key| Array === key && key.size == @index_fields.size}
|
99
|
+
)
|
100
|
+
_flat_uniq keys.map{|key| _detect_shard(key)}
|
101
|
+
elsif pos = @shard_for_index[index_no]
|
102
|
+
_flat_uniq keys.map{|key| _detect_shard([*key].values_at(*pos)) }
|
103
|
+
else
|
104
|
+
_all_shards
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def _detect_shards_for_key(key, index_no)
|
109
|
+
if index_no == @shard_by_index
|
110
|
+
_detect_shard(key)
|
111
|
+
elsif pos = @shard_for_index[index_no]
|
112
|
+
_detect_shard(key.values_at(*pos))
|
113
|
+
else
|
114
|
+
_all_shards
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def _detect_shards(keys)
|
119
|
+
_flat_uniq keys.map{|key| _detect_shard(key)}
|
120
|
+
end
|
121
|
+
|
122
|
+
def _detect_shards_for_insert(keys)
|
123
|
+
_flat_uniq keys.map{|key| _detect_shard_for_insert(key)}
|
124
|
+
end
|
125
|
+
|
126
|
+
def _flat_uniq(array)
|
127
|
+
hsh = {}
|
128
|
+
array.each do |v|
|
129
|
+
if v.respond_to?(:each)
|
130
|
+
v.each{|vv| hsh[vv] = true}
|
131
|
+
else
|
132
|
+
hsh[v] = true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
hsh.keys
|
136
|
+
end
|
137
|
+
|
138
|
+
def _detect_shard_for_insert(shard_values)
|
139
|
+
shard_values = [shard_values] unless Array === shard_values
|
140
|
+
@shard_proc.call(shard_values, @insert_with_shards_count, self) || _all_shards
|
141
|
+
end
|
142
|
+
|
143
|
+
def _detect_shard(shard_values)
|
144
|
+
shard_values = [shard_values] unless Array === shard_values
|
145
|
+
shards = @shard_proc.call(shard_values, @shards_count, self) || _all_shards
|
146
|
+
if @previous_shards_count
|
147
|
+
prev_shards = @shard_proc.call(shard_values, @previous_shards_count, self) || _all_shards
|
148
|
+
shards = [*shards, *prev_shards].uniq
|
149
|
+
end
|
150
|
+
shards
|
151
|
+
end
|
152
|
+
|
153
|
+
def _get_shard_nums
|
154
|
+
@shards_count == 1 ? @default_shard : yield
|
155
|
+
end
|
156
|
+
|
157
|
+
def _all_shards
|
158
|
+
(0...@shards_count).to_a
|
159
|
+
end
|
160
|
+
|
161
|
+
def detect_shard(shard_values)
|
162
|
+
@shards_count == 1 ? @default_shard : _detect_shard(shard_values)
|
163
|
+
end
|
164
|
+
|
165
|
+
def detect_shard_for_insert(shard_values)
|
166
|
+
@shards_count == 1 ? @default_shard : _detect_shard_for_insert(shard_values)
|
167
|
+
end
|
168
|
+
|
169
|
+
def detect_shards(shard_values)
|
170
|
+
@shards_count == 1 ? @default_shard : _detect_shards(shard_values)
|
171
|
+
end
|
172
|
+
|
173
|
+
def detect_shards_for_insert(shard_values)
|
174
|
+
@shards_count == 1 ? @default_shard : _detect_shards_for_insert(shard_values)
|
175
|
+
end
|
176
|
+
|
177
|
+
def all_shards
|
178
|
+
@shards_count == 1 ? @default_shard : (0...@shards_count).to_a
|
179
|
+
end
|
180
|
+
|
181
|
+
def shard(shard_number)
|
182
|
+
case shard_number
|
183
|
+
when Integer
|
184
|
+
if shard_number >= @shards_count
|
185
|
+
raise ArgumentError, "There is no shard #{shard_number}, amount of shards is #{@shards_count}"
|
186
|
+
end
|
187
|
+
when Array
|
188
|
+
shard_number.each do|i|
|
189
|
+
if i >= @shards_count
|
190
|
+
raise ArgumentError, "There is no shard #{i}, amount of shards is #{@shards_count}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
else
|
194
|
+
raise ArgumentError, "Shard number should be integer or array of integers"
|
195
|
+
end
|
196
|
+
(@_fixed_shards ||= {})[shard_number] ||=
|
197
|
+
clone.instance_exec do
|
198
|
+
@shards_count = 1
|
199
|
+
@default_shard = shard_number
|
200
|
+
self
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -6,10 +6,11 @@ require 'tarantool/core-ext'
|
|
6
6
|
|
7
7
|
module Tarantool
|
8
8
|
class SpaceArray
|
9
|
+
include CommonSpace
|
9
10
|
include Request
|
10
11
|
include Util::Array
|
11
12
|
|
12
|
-
def initialize(tarantool, space_no, fields, indexes)
|
13
|
+
def initialize(tarantool, space_no, fields, indexes, shard_fields = nil, shard_proc = nil)
|
13
14
|
@tarantool = tarantool
|
14
15
|
@space_no = space_no
|
15
16
|
|
@@ -24,9 +25,18 @@ module Tarantool
|
|
24
25
|
@index_fields = indexes
|
25
26
|
@indexes = _map_indexes(indexes)
|
26
27
|
else
|
27
|
-
@index_fields =
|
28
|
+
@index_fields = []
|
28
29
|
@indexes = [TYPES_FALLBACK]
|
29
30
|
end
|
31
|
+
|
32
|
+
shard_fields ||= @index_fields[0]
|
33
|
+
unless shard_fields || @tarantool.shards_count == 1
|
34
|
+
raise ArgumentError, "You could not use space without specifying primary key or shard fields when shards count is greater than 1"
|
35
|
+
else
|
36
|
+
@shard_fields = [*shard_fields]
|
37
|
+
@shard_positions = @shard_fields
|
38
|
+
_init_shard_vars(shard_proc)
|
39
|
+
end
|
30
40
|
end
|
31
41
|
|
32
42
|
def _map_indexes(indexes)
|
@@ -40,10 +50,6 @@ module Tarantool
|
|
40
50
|
end.freeze
|
41
51
|
end
|
42
52
|
|
43
|
-
def _send_request(type, body, cb)
|
44
|
-
@tarantool._send_request(type, body, cb)
|
45
|
-
end
|
46
|
-
|
47
53
|
def all_by_pks_cb(keys, cb, opts={})
|
48
54
|
all_by_keys_cb(0, keys, cb, opts)
|
49
55
|
end
|
@@ -76,7 +82,7 @@ module Tarantool
|
|
76
82
|
|
77
83
|
def select_cb(index_no, keys, offset, limit, cb)
|
78
84
|
if Array === index_no
|
79
|
-
raise ArgumentError, "Has no defined indexes to search index #{index_no}"
|
85
|
+
raise ArgumentError, "Has no defined indexes to search index #{index_no}" if @index_fields.empty?
|
80
86
|
index_fields = index_no
|
81
87
|
index_no = @index_fields.index{|fields| fields.take(index_fields.size) == index_fields}
|
82
88
|
unless index_no || index_fields.size == 1
|
@@ -87,7 +93,7 @@ module Tarantool
|
|
87
93
|
end
|
88
94
|
end
|
89
95
|
end
|
90
|
-
|
96
|
+
unless @index_fields.empty?
|
91
97
|
unless index_types = @indexes[index_no]
|
92
98
|
raise ArgumentError, "No index ##{index_no}"
|
93
99
|
end
|
@@ -95,27 +101,46 @@ module Tarantool
|
|
95
101
|
index_types = _detect_types([*[*keys][0]])
|
96
102
|
end
|
97
103
|
|
98
|
-
|
104
|
+
shard_nums = _get_shard_nums { _detect_shards_for_keys(keys, index_no) }
|
105
|
+
|
106
|
+
_select(@space_no, index_no, offset, limit, keys, cb, @fields, index_types, shard_nums)
|
99
107
|
end
|
100
108
|
|
101
109
|
def insert_cb(tuple, cb, opts = {})
|
102
|
-
|
110
|
+
shard_nums = detect_shard_for_insert(tuple.values_at(*@shard_positions))
|
111
|
+
_insert(@space_no, BOX_ADD, tuple, @fields, cb, opts[:return_tuple], shard_nums)
|
103
112
|
end
|
104
113
|
|
105
114
|
def replace_cb(tuple, cb, opts = {})
|
106
|
-
|
115
|
+
shard_nums = detect_shard(tuple.values_at(*@shard_positions))
|
116
|
+
_insert(@space_no, BOX_REPLACE, tuple, @fields,
|
117
|
+
cb, opts[:return_tuple], shard_nums, opts.fetch(:in_any_shard, true))
|
118
|
+
end
|
119
|
+
|
120
|
+
def store_cb(tuple, cb, opts = {})
|
121
|
+
shard_nums = _get_shard_nums{
|
122
|
+
if opts.fetch(:to_insert_shard, true)
|
123
|
+
_detect_shard_for_insert(tuple.values_at(*@shard_positions))
|
124
|
+
else
|
125
|
+
_detect_shard(tuple.values_at(*@shard_positions))
|
126
|
+
end
|
127
|
+
}
|
128
|
+
_insert(@space_no, 0, tuple, @fields, cb, opts[:return_tuple], shard_nums)
|
107
129
|
end
|
108
130
|
|
109
131
|
def update_cb(pk, operations, cb, opts = {})
|
132
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_key(pk, 0) }
|
110
133
|
_update(@space_no, pk, operations, @fields,
|
111
134
|
@indexes[0] || _detect_types([*pk]),
|
112
|
-
cb, opts[:return_tuple]
|
135
|
+
cb, opts[:return_tuple],
|
136
|
+
shard_nums)
|
113
137
|
end
|
114
138
|
|
115
139
|
def delete_cb(pk, cb, opts = {})
|
140
|
+
shard_nums = _get_shard_nums{ _detect_shards_for_key(pk, 0) }
|
116
141
|
_delete(@space_no, pk, @fields,
|
117
142
|
@indexes[0] || _detect_types([*pk]),
|
118
|
-
cb, opts[:return_tuple])
|
143
|
+
cb, opts[:return_tuple], shard_nums)
|
119
144
|
end
|
120
145
|
|
121
146
|
def invoke_cb(func_name, values, cb, opts = {})
|