aerospike 2.24.0 → 2.26.0

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.
@@ -0,0 +1,403 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2022 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License") you may n
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ module Aerospike
18
+
19
+ # List expression generator. See {@link Exp}.
20
+ #
21
+ # The bin expression argument in these methods can be a reference to a bin or the
22
+ # result of another expression. Expressions that modify bin values are only used
23
+ # for temporary expression evaluation and are not permanently applied to the bin.
24
+ #
25
+ # List modify expressions the bin's value. This value will be a list except
26
+ # when the list is nested within a map. In that case, a map is returned for the
27
+ # list modify expression.
28
+ #
29
+ # List expressions support negative indexing. If the index is negative, the
30
+ # resolved index starts backwards from end of list. If an index is out of bounds,
31
+ # a parameter error will be returned. If a range is partially out of bounds, the
32
+ # valid part of the range will be returned. Index/Range examples:
33
+ #
34
+ # Index 0: First item in list.
35
+ # Index 4: Fifth item in list.
36
+ # Index -1: Last item in list.
37
+ # Index -3: Third to last item in list.
38
+ # Index 1 Count 2: Second and third items in list.
39
+ # Index -3 Count 3: Last three items in list.
40
+ # Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
41
+ #
42
+ # Nested expressions are supported by optional CTX context arguments. Example:
43
+ #
44
+ # bin = [[7,9,5],[1,2,3],[6,5,4,1]]
45
+ # Get size of last list.
46
+ # ListExp.size(Exp.listBin("bin"), CTX.listIndex(-1))
47
+ # result = 4
48
+ class Exp::List
49
+
50
+ # Create expression that appends value to end of list.
51
+ def self.append(value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
52
+ bytes = Exp.pack(ctx, APPEND, value, policy.order, policy.flags)
53
+ self.add_write(bin, bytes, ctx)
54
+ end
55
+
56
+ # Create expression that appends list items to end of list.
57
+ def self.append_items(list, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
58
+ bytes = Exp.pack(ctx, APPEND_ITEMS, list, policy.order, policy.flags)
59
+ self.add_write(bin, bytes, ctx)
60
+ end
61
+
62
+ # Create expression that inserts value to specified index of list.
63
+ def self.insert(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
64
+ bytes = Exp.pack(ctx, INSERT, index, value, policy.flags)
65
+ self.add_write(bin, bytes, ctx)
66
+ end
67
+
68
+ # Create expression that inserts each input list item starting at specified index of list.
69
+ def self.insert_items(index, list, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
70
+ bytes = Exp.pack(ctx, INSERT_ITEMS, index, list, policy.flags)
71
+ self.add_write(bin, bytes, ctx)
72
+ end
73
+
74
+ # Create expression that increments list[index] by value.
75
+ # Value expression should resolve to a number.
76
+ def self.increment(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
77
+ bytes = Exp.pack(ctx, INCREMENT, index, value, policy.order, policy.flags)
78
+ self.add_write(bin, bytes, ctx)
79
+ end
80
+
81
+ # Create expression that sets item value at specified index in list.
82
+ def self.set(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
83
+ bytes = Exp.pack(ctx, SET, index, value, policy.flags)
84
+ self.add_write(bin, bytes, ctx)
85
+ end
86
+
87
+ # Create expression that removes all items in list.
88
+ def self.clear(bin, ctx: nil)
89
+ bytes = Exp.pack(ctx, CLEAR)
90
+ self.add_write(bin, bytes, ctx)
91
+ end
92
+
93
+ # Create expression that sorts list according to sort_flags.
94
+ #
95
+ # @param sort_flags sort flags. See {@link ListSortFlagsend.
96
+ # @param bin bin or list value expression
97
+ # @param ctx optional context path for nested CDT
98
+ def self.sort(sort_flags, bin, ctx: nil)
99
+ bytes = Exp.pack(ctx, SORT, sort_flags)
100
+ self.add_write(bin, bytes, ctx)
101
+ end
102
+
103
+ # Create expression that removes list items identified by value.
104
+ def self.remove_by_value(value, bin, ctx: nil)
105
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE, CDT::ListReturnType::NONE, value)
106
+ self.add_write(bin, bytes, ctx)
107
+ end
108
+
109
+ # Create expression that removes list items identified by values.
110
+ def self.remove_by_value_list(values, bin, ctx: nil)
111
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_LIST, CDT::ListReturnType::NONE, values)
112
+ self.add_write(bin, bytes, ctx)
113
+ end
114
+
115
+ # Create expression that removes list items identified by value range (value_begin inclusive, value_end exclusive).
116
+ # If value_begin is nil, the range is less than value_end. If value_end is nil, the range is
117
+ # greater than equal to value_begin.
118
+ def self.remove_by_value_range(value_begin, value_end, bin, ctx: nil)
119
+ bytes = self.pack_range_operation(REMOVE_BY_VALUE_INTERVAL, CDT::ListReturnType::NONE, value_begin, value_end, ctx)
120
+ self.add_write(bin, bytes, ctx)
121
+ end
122
+
123
+ # Create expression that removes list items nearest to value and greater by relative rank with a count limit if provided.
124
+ #
125
+ # Examples for ordered list [0,4,5,9,11,15]:
126
+ #
127
+ # (value,rank,count) = [removed items]
128
+ # (5,0,2) = [5,9]
129
+ # (5,1,1) = [9]
130
+ # (5,-1,2) = [4,5]
131
+ # (3,0,1) = [4]
132
+ # (3,3,7) = [11,15]
133
+ # (3,-3,2) = []
134
+ def self.remove_by_value_relative_rank_range(value, rank, bin, ctx: nil, count: nil)
135
+ unless count.nil?
136
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::ListReturnType::NONE, value, rank, count)
137
+ else
138
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::ListReturnType::NONE, value, rank)
139
+ end
140
+ self.add_write(bin, bytes, ctx)
141
+ end
142
+
143
+ # Create expression that removes list item identified by index.
144
+ def self.remove_by_index(index, bin, ctx: nil)
145
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX, CDT::ListReturnType::NONE, index)
146
+ self.add_write(bin, bytes, ctx)
147
+ end
148
+
149
+ # Create expression that removes "count" list items starting at specified index.
150
+ def self.remove_by_index_range(index, bin, ctx: nil, count: nil)
151
+ unless count.nil?
152
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::ListReturnType::NONE, index, count)
153
+ else
154
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::ListReturnType::NONE, index)
155
+ end
156
+ self.add_write(bin, bytes, ctx)
157
+ end
158
+
159
+ # Create expression that removes list item identified by rank.
160
+ def self.remove_by_rank(rank, bin, ctx: nil)
161
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK, CDT::ListReturnType::NONE, rank)
162
+ self.add_write(bin, bytes, ctx)
163
+ end
164
+
165
+ # Create expression that removes "count" list items starting at specified rank.
166
+ def self.remove_by_rank_range(rank, bin, ctx: nil, count: nil)
167
+ unless count.nil?
168
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::ListReturnType::NONE, rank, count)
169
+ else
170
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::ListReturnType::NONE, rank)
171
+ end
172
+ self.add_write(bin, bytes, ctx)
173
+ end
174
+
175
+ # Create expression that returns list size.
176
+ #
177
+ # ==== Examples
178
+ # # List bin "a" size > 7
179
+ # Exp.gt(ListExp.size(Exp.listBin("a")), Exp.val(7))
180
+ # end</pre>
181
+ def self.size(bin, ctx: nil)
182
+ bytes = Exp.pack(ctx, SIZE)
183
+ self.add_read(bin, bytes, Exp::Type::INT)
184
+ end
185
+
186
+ # Create expression that selects list items identified by value and returns selected
187
+ # data specified by return_type.
188
+ #
189
+ # ==== Examples
190
+ # # List bin "a" contains at least one item == "abc"
191
+ # Exp.gt(
192
+ # ListExp.getByValue(CDT::ListReturnType::COUNT, Exp.val("abc"), Exp.listBin("a")),
193
+ # Exp.val(0))
194
+ # end</pre>
195
+ #
196
+ # @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
197
+ # @param value search expression
198
+ # @param bin list bin or list value expression
199
+ # @param ctx optional context path for nested CDT
200
+ def self.get_by_value(return_type, value, bin, ctx: nil)
201
+ bytes = Exp.pack(ctx, GET_BY_VALUE, return_type, value)
202
+ self.add_read(bin, bytes, get_value_type(return_type))
203
+ end
204
+
205
+ # Create expression that selects list items identified by value range and returns selected data
206
+ # specified by return_type.
207
+ #
208
+ # ==== Examples
209
+ # # List bin "a" items >= 10 && items < 20
210
+ # ListExp.getByValueRange(CDT::ListReturnType::VALUE, Exp.val(10), Exp.val(20), Exp.listBin("a"))
211
+ # end</pre>
212
+ #
213
+ # @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
214
+ # @param value_begin begin expression inclusive. If nil, range is less than value_end.
215
+ # @param value_end end expression exclusive. If nil, range is greater than equal to value_begin.
216
+ # @param bin bin or list value expression
217
+ # @param ctx optional context path for nested CDT
218
+ def self.get_by_value_range(return_type, value_begin, value_end, bin, ctx: nil)
219
+ bytes = self.pack_range_operation(GET_BY_VALUE_INTERVAL, return_type, value_begin, value_end, ctx)
220
+ self.add_read(bin, bytes, get_value_type(return_type))
221
+ end
222
+
223
+ # Create expression that selects list items identified by values and returns selected data
224
+ # specified by return_type.
225
+ def self.get_by_value_list(return_type, values, bin, ctx: nil)
226
+ bytes = Exp.pack(ctx, GET_BY_VALUE_LIST, return_type, values)
227
+ self.add_read(bin, bytes, get_value_type(return_type))
228
+ end
229
+
230
+ # Create expression that selects list items nearest to value and greater by relative rank with a count limit
231
+ # and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
232
+ #
233
+ # Examples for ordered list [0,4,5,9,11,15]:
234
+ #
235
+ # (value,rank,count) = [selected items]
236
+ # (5,0,2) = [5,9]
237
+ # (5,1,1) = [9]
238
+ # (5,-1,2) = [4,5]
239
+ # (3,0,1) = [4]
240
+ # (3,3,7) = [11,15]
241
+ # (3,-3,2) = []
242
+ def self.get_by_value_relative_rank_range(return_type, value, rank, bin, ctx: nil, count: nil)
243
+ unless count.nil?
244
+ bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank, count)
245
+ else
246
+ bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank)
247
+ end
248
+ self.add_read(bin, bytes, get_value_type(return_type))
249
+ end
250
+
251
+ # Create expression that selects list item identified by index and returns
252
+ # selected data specified by return_type.
253
+ #
254
+ # ==== Examples
255
+ # # a[3] == 5
256
+ # Exp.eq(
257
+ # ListExp.getByIndex(CDT::ListReturnType::VALUE, Exp::Type::INT, Exp.val(3), Exp.listBin("a")),
258
+ # Exp.val(5))
259
+ # end</pre>
260
+ #
261
+ # @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
262
+ # @param value_type expected type of value
263
+ # @param index list index expression
264
+ # @param bin list bin or list value expression
265
+ # @param ctx optional context path for nested CDT
266
+ def self.get_by_index(return_type, value_type, index, bin, ctx: nil)
267
+ bytes = Exp.pack(ctx, GET_BY_INDEX, return_type, index)
268
+ self.add_read(bin, bytes, value_type)
269
+ end
270
+
271
+ # Create expression that selects list items starting at specified index to the end of list
272
+ # and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
273
+ def self.get_by_index_range(return_type, index, bin, ctx: nil)
274
+ bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index)
275
+ self.add_read(bin, bytes, get_value_type(return_type))
276
+ end
277
+
278
+ # Create expression that selects "count" list items starting at specified index
279
+ # and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
280
+ def self.get_by_index_range(return_type, index, bin, ctx: nil, count: nil)
281
+ unless count.nil?
282
+ bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index, count)
283
+ else
284
+ bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index)
285
+ end
286
+ self.add_read(bin, bytes, get_value_type(return_type))
287
+ end
288
+
289
+ # Create expression that selects list item identified by rank and returns selected
290
+ # data specified by return_type.
291
+ #
292
+ # ==== Examples
293
+ # # Player with lowest score.
294
+ # ListExp.getByRank(CDT::ListReturnType::VALUE, Type.STRING, Exp.val(0), Exp.listBin("a"))
295
+ # end</pre>
296
+ #
297
+ # @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
298
+ # @param value_type expected type of value
299
+ # @param rank rank expression
300
+ # @param bin list bin or list value expression
301
+ # @param ctx optional context path for nested CDT
302
+ def self.get_by_rank(return_type, value_type, rank, bin, ctx: nil)
303
+ bytes = Exp.pack(ctx, GET_BY_RANK, return_type, rank)
304
+ self.add_read(bin, bytes, value_type)
305
+ end
306
+
307
+ # Create expression that selects list items starting at specified rank to the last ranked item
308
+ # and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
309
+ def self.get_by_rank_range(return_type, rank, bin, ctx: nil)
310
+ bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank)
311
+ self.add_read(bin, bytes, get_value_type(return_type))
312
+ end
313
+
314
+ # Create expression that selects "count" list items starting at specified rank and returns
315
+ # selected data specified by return_type (See {@link CDT::ListReturnTypeend).
316
+ def self.get_by_rank_range(return_type, rank, bin, ctx: nil, count: nil)
317
+ unless count.nil?
318
+ bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank, count)
319
+ else
320
+ bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank)
321
+ end
322
+ self.add_read(bin, bytes, get_value_type(return_type))
323
+ end
324
+
325
+ private
326
+
327
+ MODULE = 0
328
+ APPEND = 1
329
+ APPEND_ITEMS = 2
330
+ INSERT = 3
331
+ INSERT_ITEMS = 4
332
+ SET = 9
333
+ CLEAR = 11
334
+ INCREMENT = 12
335
+ SORT = 13
336
+ SIZE = 16
337
+ GET_BY_INDEX = 19
338
+ GET_BY_RANK = 21
339
+ GET_BY_VALUE = 22 # GET_ALL_BY_VALUE on server
340
+ GET_BY_VALUE_LIST = 23
341
+ GET_BY_INDEX_RANGE = 24
342
+ GET_BY_VALUE_INTERVAL = 25
343
+ GET_BY_RANK_RANGE = 26
344
+ GET_BY_VALUE_REL_RANK_RANGE = 27
345
+ REMOVE_BY_INDEX = 32
346
+ REMOVE_BY_RANK = 34
347
+ REMOVE_BY_VALUE = 35
348
+ REMOVE_BY_VALUE_LIST = 36
349
+ REMOVE_BY_INDEX_RANGE = 37
350
+ REMOVE_BY_VALUE_INTERVAL = 38
351
+ REMOVE_BY_RANK_RANGE = 39
352
+ REMOVE_BY_VALUE_REL_RANK_RANGE = 40
353
+
354
+ def self.add_write(bin, bytes, ctx)
355
+ if ctx.to_a.empty?
356
+ ret_type = Exp::Type::LIST
357
+ else
358
+ ret_type = ((ctx[0].id & 0x10) == 0) ? Exp::Type::MAP : Exp::Type::LIST
359
+ end
360
+ Exp::Module.new(bin, bytes, ret_type, MODULE | Exp::MODIFY)
361
+ end
362
+
363
+ def self.add_read(bin, bytes, ret_type)
364
+ Exp::Module.new(bin, bytes, ret_type, MODULE)
365
+ end
366
+
367
+ def self.get_value_type(return_type)
368
+ if (return_type & ~CDT::ListReturnType::INVERTED) == CDT::ListReturnType::VALUE
369
+ Exp::Type::LIST
370
+ else
371
+ Exp::Type::INT
372
+ end
373
+ end
374
+
375
+ def self.pack_range_operation(command, return_type, value_begin, value_end, ctx)
376
+ Packer.use do |packer|
377
+ Exp.pack_ctx(packer, ctx)
378
+ packer.write_array_header(value_end.nil? ? 3 : 4)
379
+ packer.write(command)
380
+ packer.write(return_type)
381
+
382
+ unless value_begin.nil?
383
+ if value_begin.is_a?(Exp)
384
+ value_begin.pack(packer)
385
+ else
386
+ Value.of(value_begin).pack(packer)
387
+ end
388
+ else
389
+ packer.write(nil)
390
+ end
391
+
392
+ unless value_end.nil?
393
+ if value_end.is_a?(Exp)
394
+ value_end.pack(packer)
395
+ else
396
+ Value.of(value_end).pack(packer)
397
+ end
398
+ end
399
+ packer.bytes
400
+ end
401
+ end
402
+ end # class Exp::List
403
+ end # module