@@ -2,15 +2,13 @@ local checks = require('checks')
2
2
local errors = require (' errors' )
3
3
local vshard = require (' vshard' )
4
4
5
- local call = require (' crud.common.call' )
6
5
local registry = require (' crud.common.registry' )
7
6
local utils = require (' crud.common.utils' )
8
7
local dev_checks = require (' crud.common.dev_checks' )
9
8
10
9
local select_conditions = require (' crud.select.conditions' )
11
10
local select_plan = require (' crud.select.plan' )
12
11
local select_executor = require (' crud.select.executor' )
13
- local select_comparators = require (' crud.select.comparators' )
14
12
local select_filters = require (' crud.select.filters' )
15
13
16
14
local Iterator = require (' crud.select.iterator' )
@@ -21,9 +19,20 @@ local GetReplicasetsError = errors.new_class('GetReplicasetsError')
21
19
local select_module = {}
22
20
23
21
local SELECT_FUNC_NAME = ' __select'
24
-
25
22
local DEFAULT_BATCH_SIZE = 100
26
23
24
+ local function make_cursor (opts , data )
25
+ local last_tuple = data [# data ]
26
+
27
+ return {
28
+ scan_value = opts .scan_value ,
29
+ after_tuple = last_tuple ,
30
+ iter = opts .iter ,
31
+ limit = opts .limit ,
32
+ scan_condition_num = opts .scan_condition_num ,
33
+ }
34
+ end
35
+
27
36
local function call_select_on_storage (space_name , index_id , conditions , opts )
28
37
dev_checks (' string' , ' number' , ' ?table' , {
29
38
scan_value = ' table' ,
@@ -62,7 +71,14 @@ local function call_select_on_storage(space_name, index_id, conditions, opts)
62
71
return nil , SelectError :new (" Failed to execute select: %s" , err )
63
72
end
64
73
65
- return tuples
74
+ local cursor
75
+ if # tuples < opts .limit or opts .limit == 0 then
76
+ cursor = {is_end = true }
77
+ else
78
+ cursor = make_cursor (opts , tuples )
79
+ end
80
+
81
+ return cursor , tuples
66
82
end
67
83
68
84
function select_module .init ()
@@ -71,39 +87,6 @@ function select_module.init()
71
87
})
72
88
end
73
89
74
- local function select_iteration (space_name , plan , opts )
75
- dev_checks (' string' , ' ?table' , {
76
- after_tuple = ' ?table' ,
77
- replicasets = ' table' ,
78
- timeout = ' ?number' ,
79
- limit = ' number' ,
80
- })
81
-
82
- -- call select on storages
83
- local storage_select_opts = {
84
- scan_value = plan .scan_value ,
85
- after_tuple = opts .after_tuple ,
86
- iter = plan .iter ,
87
- limit = opts .limit ,
88
- scan_condition_num = plan .scan_condition_num ,
89
- }
90
-
91
- local storage_select_args = {
92
- space_name , plan .index_id , plan .conditions , storage_select_opts ,
93
- }
94
-
95
- local results , err = call .ro (SELECT_FUNC_NAME , storage_select_args , {
96
- replicasets = opts .replicasets ,
97
- timeout = opts .timeout ,
98
- })
99
-
100
- if err ~= nil then
101
- return nil , err
102
- end
103
-
104
- return results
105
- end
106
-
107
90
local function get_replicasets_by_sharding_key (sharding_key )
108
91
local bucket_id = vshard .router .bucket_id_strcrc32 (sharding_key )
109
92
local replicaset , err = vshard .router .route (bucket_id )
@@ -130,8 +113,6 @@ local function build_select_iterator(space_name, user_conditions, opts)
130
113
return nil , SelectError :new (" batch_size should be > 0" )
131
114
end
132
115
133
- local batch_size = opts .batch_size or DEFAULT_BATCH_SIZE
134
-
135
116
-- check conditions
136
117
local conditions , err = select_conditions .parse (user_conditions )
137
118
if err ~= nil then
@@ -169,33 +150,21 @@ local function build_select_iterator(space_name, user_conditions, opts)
169
150
replicasets_to_select = get_replicasets_by_sharding_key (plan .sharding_key )
170
151
end
171
152
172
- -- generate tuples comparator
173
- local scan_index = space .index [plan .index_id ]
174
- local primary_index = space .index [0 ]
175
- local cmp_key_parts = utils .merge_primary_key_parts (scan_index .parts , primary_index .parts )
176
- local cmp_operator = select_comparators .get_cmp_operator (plan .iter )
177
- local tuples_comparator , err = select_comparators .gen_tuples_comparator (
178
- cmp_operator , cmp_key_parts
179
- )
180
- if err ~= nil then
181
- return nil , SelectError :new (" Failed to generate comparator function: %s" , err )
182
- end
183
-
184
- local iter = Iterator .new ({
185
- space_name = space_name ,
186
- space_format = space_format ,
187
- iteration_func = select_iteration ,
188
- comparator = tuples_comparator ,
189
-
190
- plan = plan ,
191
-
192
- batch_size = batch_size ,
193
- replicasets = replicasets_to_select ,
153
+ local select_opts = {
154
+ scan_value = plan .scan_value ,
155
+ after_tuple = plan .after_tuple ,
156
+ iter = plan .iter ,
157
+ limit = opts .batch_size or DEFAULT_BATCH_SIZE ,
158
+ scan_condition_num = plan .scan_condition_num ,
159
+ }
194
160
195
- timeout = opts . timeout ,
196
- } )
161
+ local iter = Iterator . new ( replicasets_to_select ,
162
+ space_name , plan . index_id , plan . conditions , select_opts )
197
163
198
- return iter
164
+ return {
165
+ iter = iter ,
166
+ space_format = space_format ,
167
+ }
199
168
end
200
169
201
170
function select_module .pairs (space_name , user_conditions , opts )
@@ -223,12 +192,14 @@ function select_module.pairs(space_name, user_conditions, opts)
223
192
error (string.format (" Failed to generate iterator: %s" , err ))
224
193
end
225
194
226
- local gen = function (_ , iter )
227
- if not iter :has_next () then
195
+ local tuple , _
196
+ local merger_gen = iter .iter :pairs ()
197
+ local gen = function ()
198
+ _ , tuple = merger_gen .gen (nil , merger_gen .state )
199
+ if tuple == nil then
228
200
return nil
229
201
end
230
202
231
- local tuple , err = iter :get ()
232
203
if err ~= nil then
233
204
error (string.format (" Failed to get next object: %s" , err ))
234
205
end
@@ -241,7 +212,7 @@ function select_module.pairs(space_name, user_conditions, opts)
241
212
return iter , obj
242
213
end
243
214
244
- return gen , nil , iter
215
+ return gen
245
216
end
246
217
247
218
function select_module .call (space_name , user_conditions , opts )
@@ -273,17 +244,15 @@ function select_module.call(space_name, user_conditions, opts)
273
244
274
245
local tuples = {}
275
246
276
- while iter :has_next () do
277
- local tuple , err = iter :get ()
278
- if err ~= nil then
279
- return nil , SelectError :new (" Failed to get next object: %s" , err )
280
- end
281
-
282
- if tuple == nil then
247
+ local count = 0
248
+ local first = opts .first and math.abs (opts .first )
249
+ for _ , tuple in iter .iter :pairs () do
250
+ if first ~= nil and count >= first then
283
251
break
284
252
end
285
253
286
254
table.insert (tuples , tuple )
255
+ count = count + 1
287
256
end
288
257
289
258
if opts .first ~= nil and opts .first < 0 then
0 commit comments