tarantool 0.3.0.7 → 0.4.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 = {})
|