aerospike 2.19.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +354 -244
  3. data/lib/aerospike/atomic/atomic.rb +1 -1
  4. data/lib/aerospike/cdt/context.rb +137 -70
  5. data/lib/aerospike/cdt/list_return_type.rb +4 -0
  6. data/lib/aerospike/cdt/map_operation.rb +6 -6
  7. data/lib/aerospike/cdt/map_policy.rb +16 -2
  8. data/lib/aerospike/cdt/map_return_type.rb +13 -1
  9. data/lib/aerospike/client.rb +137 -115
  10. data/lib/aerospike/cluster/create_connection.rb +1 -1
  11. data/lib/aerospike/cluster.rb +41 -4
  12. data/lib/aerospike/command/admin_command.rb +368 -52
  13. data/lib/aerospike/command/batch_index_command.rb +4 -8
  14. data/lib/aerospike/command/batch_index_exists_command.rb +1 -1
  15. data/lib/aerospike/command/batch_index_node.rb +1 -1
  16. data/lib/aerospike/command/batch_item.rb +1 -1
  17. data/lib/aerospike/command/command.rb +180 -123
  18. data/lib/aerospike/command/field_type.rb +25 -24
  19. data/lib/aerospike/command/login_command.rb +164 -0
  20. data/lib/aerospike/command/multi_command.rb +25 -2
  21. data/lib/aerospike/command/operate_args.rb +99 -0
  22. data/lib/aerospike/command/operate_command.rb +6 -11
  23. data/lib/aerospike/command/read_command.rb +2 -2
  24. data/lib/aerospike/connection/authenticate.rb +36 -3
  25. data/lib/aerospike/exp/exp.rb +1329 -0
  26. data/lib/aerospike/exp/exp_bit.rb +388 -0
  27. data/lib/aerospike/exp/exp_hll.rb +169 -0
  28. data/lib/aerospike/exp/exp_list.rb +403 -0
  29. data/lib/aerospike/exp/exp_map.rb +493 -0
  30. data/lib/aerospike/exp/operation.rb +56 -0
  31. data/lib/aerospike/features.rb +22 -9
  32. data/lib/aerospike/host/parse.rb +2 -2
  33. data/lib/aerospike/key.rb +10 -1
  34. data/lib/aerospike/node/refresh/info.rb +1 -1
  35. data/lib/aerospike/node/verify/name.rb +1 -1
  36. data/lib/aerospike/node/verify/partition_generation.rb +1 -1
  37. data/lib/aerospike/node/verify/peers_generation.rb +1 -1
  38. data/lib/aerospike/node/verify/rebalance_generation.rb +1 -1
  39. data/lib/aerospike/node_validator.rb +6 -1
  40. data/lib/aerospike/operation.rb +20 -22
  41. data/lib/aerospike/policy/auth_mode.rb +36 -0
  42. data/lib/aerospike/policy/client_policy.rb +4 -1
  43. data/lib/aerospike/policy/policy.rb +29 -13
  44. data/lib/aerospike/policy/query_policy.rb +35 -2
  45. data/lib/aerospike/policy/scan_policy.rb +19 -2
  46. data/lib/aerospike/privilege.rb +133 -0
  47. data/lib/aerospike/query/filter.rb +44 -32
  48. data/lib/aerospike/query/node_partitions.rb +39 -0
  49. data/lib/aerospike/query/partition_filter.rb +66 -0
  50. data/lib/aerospike/{command/roles.rb → query/partition_status.rb} +16 -19
  51. data/lib/aerospike/query/partition_tracker.rb +347 -0
  52. data/lib/aerospike/query/query_command.rb +20 -10
  53. data/lib/aerospike/query/query_executor.rb +71 -0
  54. data/lib/aerospike/query/query_partition_command.rb +267 -0
  55. data/lib/aerospike/query/recordset.rb +9 -9
  56. data/lib/aerospike/query/scan_command.rb +3 -2
  57. data/lib/aerospike/query/scan_executor.rb +71 -0
  58. data/lib/aerospike/query/scan_partition_command.rb +49 -0
  59. data/lib/aerospike/query/statement.rb +8 -1
  60. data/lib/aerospike/query/stream_command.rb +17 -0
  61. data/lib/aerospike/result_code.rb +83 -8
  62. data/lib/aerospike/role.rb +55 -0
  63. data/lib/aerospike/task/execute_task.rb +19 -16
  64. data/lib/aerospike/task/index_task.rb +1 -1
  65. data/lib/aerospike/user_role.rb +26 -1
  66. data/lib/aerospike/utils/buffer.rb +93 -29
  67. data/lib/aerospike/utils/packer.rb +7 -6
  68. data/lib/aerospike/utils/pool.rb +1 -1
  69. data/lib/aerospike/value/particle_type.rb +1 -12
  70. data/lib/aerospike/value/value.rb +35 -60
  71. data/lib/aerospike/version.rb +1 -1
  72. data/lib/aerospike.rb +156 -136
  73. metadata +24 -6
@@ -0,0 +1,493 @@
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 no
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
+ # Map expression generator. See {@link Exp}.
19
+ #
20
+ # The bin expression argument in these methods can be a reference to a bin or the
21
+ # result of another expression. Expressions that modify bin values are only used
22
+ # for temporary expression evaluation and are not permanently applied to the bin.
23
+ #
24
+ # Map modify expressions return the bin's value. This value will be a map except
25
+ # when the map is nested within a list. In that case, a list is returned for the
26
+ # map modify expression.
27
+ #
28
+ # All maps maintain an index and a rank. The index is the item offset from the start of the map,
29
+ # for both unordered and ordered maps. The rank is the sorted index of the value component.
30
+ # Map supports negative indexing for index and rank.
31
+ #
32
+ # Index examples:
33
+ #
34
+ # Index 0: First item in map.
35
+ # Index 4: Fifth item in map.
36
+ # Index -1: Last item in map.
37
+ # Index -3: Third to last item in map.
38
+ # Index 1 Count 2: Second and third items in map.
39
+ # Index -3 Count 3: Last three items in map.
40
+ # Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
41
+ #
42
+ # Rank examples:
43
+ #
44
+ # Rank 0: Item with lowest value rank in map.
45
+ # Rank 4: Fifth lowest ranked item in map.
46
+ # Rank -1: Item with highest ranked value in map.
47
+ # Rank -3: Item with third highest ranked value in map.
48
+ # Rank 1 Count 2: Second and third lowest ranked items in map.
49
+ # Rank -3 Count 3: Top three ranked items in map.
50
+ #
51
+ # Nested expressions are supported by optional CTX context arguments. Example:
52
+ #
53
+ # bin = {key1={key11=9,key12=4}, key2={key21=3,key22=5}}
54
+ # Set map value to 11 for map key "key21" inside of map key "key2".
55
+ # Get size of map key2.
56
+ # MapExp.size(mapBin("bin"), CTX.mapKey(Value.get("key2"))
57
+ # result = 2
58
+ class Exp::Map
59
+ # Create expression that writes key/value item to a map bin. The 'bin' expression should either
60
+ # reference an existing map bin or be a expression that returns a map.
61
+ #
62
+ # ==== Examples
63
+ # # Add entry{11,22} to existing map bin.
64
+ # e = Exp.build(MapExp.put(MapPolicy.Default, Exp.val(11), Exp.val(22), Exp.mapBin(binName)))
65
+ # client.operate(key, ExpOperation.write(binName, e, Exp::WriteFlags::DEFAULT))
66
+ #ctx,
67
+ # # Combine entry{11,22} with source map's first index entry and write resulting map to target map bin.
68
+ # e = Exp.build(
69
+ # MapExp.put(MapPolicy.Default, Exp.val(11), Exp.val(22),
70
+ # MapExp.getByIndexRange(CDT::MapReturnType::KEY_VALUE, Exp.val(0), Exp.val(1), Exp.mapBin(sourceBinName)))
71
+ # )
72
+ # client.operate(key, ExpOperation.write(target_bin_name, e, Exp::WriteFlags::DEFAULT))
73
+ def self.put(key, value, bin, ctx: nil, policy: CDT::MapPolicy::DEFAULT)
74
+ Packer.use do |packer|
75
+ if policy.flags != 0
76
+ Exp.pack_ctx(packer, ctx)
77
+ packer.write_array_header(5)
78
+ packer.write(PUT)
79
+ key.pack(packer)
80
+ value.pack(packer)
81
+ packer.write(policy.attributes)
82
+ packer.write(policy.flags)
83
+ else
84
+ if policy.item_command == REPLACE
85
+ # Replace doesn't allow map attributes because it does not create on non-existing key.
86
+ Exp.pack_ctx(packer, ctx)
87
+ packer.write_array_header(3)
88
+ packer.write(policy.item_command)
89
+ key.pack(packer)
90
+ value.pack(packer)
91
+ else
92
+ Exp.pack_ctx(packer, ctx)
93
+ packer.write_array_header(4)
94
+ packer.write(policy.item_command)
95
+ key.pack(packer)
96
+ value.pack(packer)
97
+ packer.write(policy.attributes)
98
+ end
99
+ end
100
+ self.add_write(bin, packer.bytes, ctx)
101
+ end
102
+ end
103
+
104
+ # Create expression that writes each map item to a map bin.
105
+ def self.put_items(map, bin, ctx: nil, policy: CDT::MapPolicy::DEFAULT)
106
+ Packer.use do |packer|
107
+ if policy.flags != 0
108
+ Exp.pack_ctx(packer, ctx)
109
+ packer.write_array_header(4)
110
+ packer.write(PUT_ITEMS)
111
+ map.pack(packer)
112
+ packer.write(policy.attributes)
113
+ packer.write(policy.flags)
114
+ else
115
+ if policy.items_command == REPLACE_ITEMS
116
+ # Replace doesn't allow map attributes because it does not create on non-existing key.
117
+ Exp.pack_ctx(packer, ctx)
118
+ packer.write_array_header(2)
119
+ packer.write(policy.items_command)
120
+ map.pack(packer)
121
+ else
122
+ Exp.pack_ctx(packer, ctx)
123
+ packer.write_array_header(3)
124
+ packer.write(policy.items_command)
125
+ map.pack(packer)
126
+ packer.write(policy.attributes)
127
+ end
128
+ end
129
+ self.add_write(bin, packer.bytes, ctx)
130
+ end
131
+ end
132
+
133
+ # Create expression that increments values by incr for all items identified by key.
134
+ # Valid only for numbers.
135
+ def self.increment(key, incr, bin, ctx: nil, policy: CDT::MapPolicy::DEFAULT)
136
+ bytes = Exp.pack(ctx, INCREMENT, key, incr, policy.attributes)
137
+ return self.add_write(bin, bytes, ctx)
138
+ end
139
+
140
+ # Create expression that removes all items in map.
141
+ def self.clear(bin, ctx: nil)
142
+ bytes = Exp.pack(ctx, CLEAR)
143
+ return self.add_write(bin, bytes, ctx)
144
+ end
145
+
146
+ # Create expression that removes map item identified by key.
147
+ def self.remove_by_key(key, bin, ctx: nil)
148
+ bytes = Exp.pack(ctx, REMOVE_BY_KEY, CDT::MapReturnType::NONE, key)
149
+ return self.add_write(bin, bytes, ctx)
150
+ end
151
+
152
+ # Create expression that removes map items identified by keys.
153
+ def self.remove_by_key_list(keys, bin, ctx: nil)
154
+ bytes = Exp.pack(ctx, REMOVE_BY_KEY_LIST, CDT::MapReturnType::NONE, keys)
155
+ return self.add_write(bin, bytes, ctx)
156
+ end
157
+
158
+ # Create expression that removes map items identified by key range (key_begin inclusive, key_end exclusive).
159
+ # If key_begin is nil, the range is less than key_end.
160
+ # If key_end is nil, the range is greater than equal to key_begin.
161
+ def self.remove_by_key_range(key_begin, key_end, bin, ctx: nil)
162
+ bytes = Exp::List.pack_range_operation(REMOVE_BY_KEY_INTERVAL, CDT::MapReturnType::NONE, key_begin, key_end, ctx)
163
+ return self.add_write(bin, bytes, ctx)
164
+ end
165
+
166
+ # Create expression that removes map items nearest to key and greater by index with a count limit if provided.
167
+ #
168
+ # Examples for map [{0=17},{4=2},{5=15},{9=10}]:
169
+ #
170
+ # (value,index,count) = [removed items]
171
+ # (5,0,1) = [{5=15}]
172
+ # (5,1,2) = [{9=10}]
173
+ # (5,-1,1) = [{4=2}]
174
+ # (3,2,1) = [{9=10}]
175
+ # (3,-2,2) = [{0=17}]
176
+ def self.remove_by_key_relative_index_range(key, index, bin, ctx: nil, count: nil)
177
+ unless count.nil?
178
+ bytes = Exp.pack(ctx, REMOVE_BY_KEY_REL_INDEX_RANGE, CDT::MapReturnType::NONE, key, index, count)
179
+ else
180
+ bytes = Exp.pack(ctx, REMOVE_BY_KEY_REL_INDEX_RANGE, CDT::MapReturnType::NONE, key, index)
181
+ end
182
+ return self.add_write(bin, bytes, ctx)
183
+ end
184
+
185
+ # Create expression that removes map items identified by value.
186
+ def self.remove_by_value(value, bin, ctx: nil)
187
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE, CDT::MapReturnType::NONE, value)
188
+ return self.add_write(bin, bytes, ctx)
189
+ end
190
+
191
+ # Create expression that removes map items identified by values.
192
+ def self.remove_by_value_list(values, bin, ctx: nil)
193
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_LIST, CDT::MapReturnType::NONE, values)
194
+ return self.add_write(bin, bytes, ctx)
195
+ end
196
+
197
+ # Create expression that removes map items identified by value range (valueBegin inclusive, valueEnd exclusive).
198
+ # If valueBegin is nil, the range is less than valueEnd.
199
+ # If valueEnd is nil, the range is greater than equal to valueBegin.
200
+ def self.remove_by_value_range(valueBegin, valueEnd, bin, ctx: nil)
201
+ bytes = Exp::List.pack_range_operation(REMOVE_BY_VALUE_INTERVAL, CDT::MapReturnType::NONE, valueBegin, valueEnd, ctx)
202
+ return self.add_write(bin, bytes, ctx)
203
+ end
204
+
205
+ # Create expression that removes map items nearest to value and greater by relative rank.
206
+ #
207
+ # Examples for map [{4=2},{9=10},{5=15},{0=17}]:
208
+ #
209
+ # (value,rank) = [removed items]
210
+ # (11,1) = [{0=17}]
211
+ # (11,-1) = [{9=10},{5=15},{0=17}]
212
+ def self.remove_by_value_relative_rank_range(value, rank, bin, ctx: nil)
213
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::MapReturnType::NONE, value, rank)
214
+ return self.add_write(bin, bytes, ctx)
215
+ end
216
+
217
+ # Create expression that removes map items nearest to value and greater by relative rank with a count limit.
218
+ #
219
+ # Examples for map [{4=2},{9=10},{5=15},{0=17}]:
220
+ #
221
+ # (value,rank,count) = [removed items]
222
+ # (11,1,1) = [{0=17}]
223
+ # (11,-1,1) = [{9=10}]
224
+ def self.remove_by_value_relative_rank_range(value, rank, count, bin, ctx: nil)
225
+ bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::MapReturnType::NONE, value, rank, count)
226
+ return self.add_write(bin, bytes, ctx)
227
+ end
228
+
229
+ # Create expression that removes map item identified by index.
230
+ def self.remove_by_index(index, bin, ctx: nil)
231
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX, CDT::MapReturnType::NONE, index)
232
+ return self.add_write(bin, bytes, ctx)
233
+ end
234
+
235
+ # Create expression that removes "count" map items starting at specified index limited by count if provided.
236
+ def self.remove_by_index_range(index, bin, ctx: nil, count: nil)
237
+ unless count.nil?
238
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::MapReturnType::NONE, index, count)
239
+ else
240
+ bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::MapReturnType::NONE, index)
241
+ end
242
+ return self.add_write(bin, bytes, ctx)
243
+ end
244
+
245
+ # Create expression that removes map item identified by rank.
246
+ def self.remove_by_rank(rank, bin, ctx: nil)
247
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK, CDT::MapReturnType::NONE, rank)
248
+ return self.add_write(bin, bytes, ctx)
249
+ end
250
+
251
+ # Create expression that removes "count" map items starting at specified rank. If count is not provided,
252
+ # all items until the last ranked item will be removed
253
+ def self.remove_by_rank_range(rank, bin, ctx: nil, count: nil)
254
+ unless count.nil?
255
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::MapReturnType::NONE, rank, count)
256
+ else
257
+ bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::MapReturnType::NONE, rank)
258
+ end
259
+ return self.add_write(bin, bytes, ctx)
260
+ end
261
+
262
+ # Create expression that returns list size.
263
+ #
264
+ # ==== Examples
265
+ # # Map bin "a" size > 7
266
+ # Exp.gt(MapExp.size(mapBin("a")), Exp.val(7))
267
+ def self.size(bin, ctx: nil)
268
+ bytes = Exp.pack(ctx, SIZE)
269
+ return self.add_read(bin, bytes, Exp::Type::INT)
270
+ end
271
+
272
+ # Create expression that selects map item identified by key and returns selected data
273
+ # specified by return_type.
274
+ #
275
+ # ==== Examples
276
+ # # Map bin "a" contains key "B"
277
+ # Exp.gt(
278
+ # MapExp.getByKey(CDT::MapReturnType::COUNT, Exp::Type::INT, Exp.val("B"), Exp.mapBin("a")),
279
+ # Exp.val(0))
280
+ #
281
+ # @param return_type metadata attributes to return. See {@link MapReturnType}
282
+ # @param value_type expected type of return value
283
+ # @param key map key expression
284
+ # @param bin bin or map value expression
285
+ # @param ctx optional context path for nested CDT
286
+ def self.get_by_key(return_type, value_type, key, bin, ctx: nil)
287
+ bytes = Exp.pack(ctx, GET_BY_KEY, return_type, key)
288
+ return self.add_read(bin, bytes, value_type)
289
+ end
290
+
291
+ # Create expression that selects map items identified by key range (key_begin inclusive, key_end exclusive).
292
+ # If key_begin is nil, the range is less than key_end.
293
+ # If key_end is nil, the range is greater than equal to key_begin.
294
+ #
295
+ # Expression returns selected data specified by return_type (See {@link MapReturnType}).
296
+ def self.get_by_key_range(return_type, key_begin, key_end, bin, ctx: nil)
297
+ bytes = Exp::List.pack_range_operation(GET_BY_KEY_INTERVAL, return_type, key_begin, key_end, ctx)
298
+ return self.add_read(bin, bytes, get_value_type(return_type))
299
+ end
300
+
301
+ # Create expression that selects map items identified by keys and returns selected data specified by
302
+ # return_type (See {@link MapReturnType}).
303
+ def self.get_by_key_list(return_type, keys, bin, ctx: nil)
304
+ bytes = Exp.pack(ctx, GET_BY_KEY_LIST, return_type, keys)
305
+ return self.add_read(bin, bytes, get_value_type(return_type))
306
+ end
307
+
308
+ # Create expression that selects map items nearest to key and greater by index with a coun.
309
+ # Expression returns selected data specified by return_type (See {@link MapReturnType}).
310
+ #
311
+ # Examples for ordered map [{0=17},{4=2},{5=15},{9=10}]:
312
+ #
313
+ # (value,index) = [selected items]
314
+ # (5,0) = [{5=15},{9=10}]
315
+ # (5,1) = [{9=10}]
316
+ # (5,-1) = [{4=2},{5=15},{9=10}]
317
+ # (3,2) = [{9=10}]
318
+ # (3,-2) = [{0=17},{4=2},{5=15},{9=10}]
319
+ def self.get_by_key_relative_index_range(return_type, key, index, bin, ctx: nil)
320
+ bytes = Exp.pack(ctx, GET_BY_KEY_REL_INDEX_RANGE, return_type, key, index)
321
+ return self.add_read(bin, bytes, get_value_type(return_type))
322
+ end
323
+
324
+ # Create expression that selects map items nearest to key and greater by index with a count limit if provided.
325
+ # Expression returns selected data specified by return_type (See {@link MapReturnType}).
326
+ #
327
+ # Examples for ordered map [{0=17},{4=2},{5=15},{9=10}]:
328
+ #
329
+ # (value,index,count) = [selected items]
330
+ # (5,0,1) = [{5=15}]
331
+ # (5,1,2) = [{9=10}]
332
+ # (5,-1,1) = [{4=2}]
333
+ # (3,2,1) = [{9=10}]
334
+ # (3,-2,2) = [{0=17}]
335
+ def self.get_by_key_relative_index_range(return_type, key, index, bin, ctx: nil, count: nil)
336
+ unless count.nil?
337
+ bytes = Exp.pack(ctx, GET_BY_KEY_REL_INDEX_RANGE, return_type, key, index, count)
338
+ else
339
+ bytes = Exp.pack(ctx, GET_BY_KEY_REL_INDEX_RANGE, return_type, key, index)
340
+ end
341
+ return self.add_read(bin, bytes, get_value_type(return_type))
342
+ end
343
+
344
+ # Create expression that selects map items identified by value and returns selected data
345
+ # specified by return_type.
346
+ #
347
+ # ==== Examples
348
+ # # Map bin "a" contains value "BBB"
349
+ # Exp.gt(
350
+ # MapExp.getByValue(CDT::MapReturnType::COUNT, Exp.val("BBB"), Exp.mapBin("a")),
351
+ # Exp.val(0))
352
+ #
353
+ # @param return_type metadata attributes to return. See {@link MapReturnType}
354
+ # @param value value expression
355
+ # @param bin bin or map value expression
356
+ # @param ctx optional context path for nested CDT
357
+ def self.get_by_value(return_type, value, bin, ctx: nil)
358
+ bytes = Exp.pack(ctx, GET_BY_VALUE, return_type, value)
359
+ return self.add_read(bin, bytes, get_value_type(return_type))
360
+ end
361
+
362
+ # Create expression that selects map items identified by value range (valueBegin inclusive, valueEnd exclusive)
363
+ # If valueBegin is nil, the range is less than valueEnd.
364
+ # If valueEnd is nil, the range is greater than equal to valueBegin.
365
+ #
366
+ # Expression returns selected data specified by return_type (See {@link MapReturnType}).
367
+ def self.get_by_value_range(return_type, valueBegin, valueEnd, bin, ctx: nil)
368
+ bytes = Exp::List.pack_range_operation(GET_BY_VALUE_INTERVAL, return_type, valueBegin, valueEnd, ctx)
369
+ return self.add_read(bin, bytes, get_value_type(return_type))
370
+ end
371
+
372
+ # Create expression that selects map items identified by values and returns selected data specified by
373
+ # return_type (See {@link MapReturnType}).
374
+ def self.get_by_value_list(return_type, values, bin, ctx: nil)
375
+ bytes = Exp.pack(ctx, GET_BY_VALUE_LIST, return_type, values)
376
+ return self.add_read(bin, bytes, get_value_type(return_type))
377
+ end
378
+
379
+ # Create expression that selects map items nearest to value and greater by relative rank (with a count limit if passed).
380
+ # Expression returns selected data specified by return_type (See {@link MapReturnType}).
381
+ #
382
+ # Examples for map [{4=2},{9=10},{5=15},{0=17}]:
383
+ #
384
+ # (value,rank) = [selected items]
385
+ # (11,1) = [{0=17}]
386
+ # (11,-1) = [{9=10},{5=15},{0=17}]
387
+ def self.get_by_value_relative_rank_range(return_type, value, rank, bin, ctx: nil, count: nil)
388
+ unless count.nil?
389
+ bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank, count)
390
+ else
391
+ bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank)
392
+ end
393
+ return self.add_read(bin, bytes, get_value_type(return_type))
394
+ end
395
+
396
+ # Create expression that selects map item identified by index and returns selected data specified by
397
+ # return_type (See {@link MapReturnType}).
398
+ def self.get_by_index(return_type, value_type, index, bin, ctx: nil)
399
+ bytes = Exp.pack(ctx, GET_BY_INDEX, return_type, index)
400
+ return self.add_read(bin, bytes, value_type)
401
+ end
402
+
403
+ # Create expression that selects map items starting at specified index to the end of map and returns selected
404
+ # data specified by return_type (See {@link MapReturnType}) limited by count if provided.
405
+ def self.get_by_index_range(return_type, index, bin, ctx: nil, count: nil)
406
+ unless count.nil?
407
+ bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index, count)
408
+ else
409
+ bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index)
410
+ end
411
+ return self.add_read(bin, bytes, get_value_type(return_type))
412
+ end
413
+
414
+ # Create expression that selects map item identified by rank and returns selected data specified by
415
+ # return_type (See {@link MapReturnType}).
416
+ def self.get_by_rank(return_type, value_type, rank, bin, ctx: nil)
417
+ bytes = Exp.pack(ctx, GET_BY_RANK, return_type, rank)
418
+ return self.add_read(bin, bytes, value_type)
419
+ end
420
+
421
+ # Create expression that selects map items starting at specified rank to the last ranked item and
422
+ # returns selected data specified by return_type (See {@link MapReturnType}).
423
+ def self.get_by_rank_range(return_type, rank, bin, ctx: nil, count: nil)
424
+ unless count.nil?
425
+ bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank, count)
426
+ else
427
+ bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank)
428
+ end
429
+ return self.add_read(bin, bytes, get_value_type(return_type))
430
+ end
431
+
432
+ private
433
+
434
+ MODULE = 0
435
+ PUT = 67
436
+ PUT_ITEMS = 68
437
+ REPLACE = 69
438
+ REPLACE_ITEMS = 70
439
+ INCREMENT = 73
440
+ CLEAR = 75
441
+ REMOVE_BY_KEY = 76
442
+ REMOVE_BY_INDEX = 77
443
+ REMOVE_BY_RANK = 79
444
+ REMOVE_BY_KEY_LIST = 81
445
+ REMOVE_BY_VALUE = 82
446
+ REMOVE_BY_VALUE_LIST = 83
447
+ REMOVE_BY_KEY_INTERVAL = 84
448
+ REMOVE_BY_INDEX_RANGE = 85
449
+ REMOVE_BY_VALUE_INTERVAL = 86
450
+ REMOVE_BY_RANK_RANGE = 87
451
+ REMOVE_BY_KEY_REL_INDEX_RANGE = 88
452
+ REMOVE_BY_VALUE_REL_RANK_RANGE = 89
453
+ SIZE = 96
454
+ GET_BY_KEY = 97
455
+ GET_BY_INDEX = 98
456
+ GET_BY_RANK = 100
457
+ GET_BY_VALUE = 102; # GET_ALL_BY_VALUE on server
458
+ GET_BY_KEY_INTERVAL = 103
459
+ GET_BY_INDEX_RANGE = 104
460
+ GET_BY_VALUE_INTERVAL = 105
461
+ GET_BY_RANK_RANGE = 106
462
+ GET_BY_KEY_LIST = 107
463
+ GET_BY_VALUE_LIST = 108
464
+ GET_BY_KEY_REL_INDEX_RANGE = 109
465
+ GET_BY_VALUE_REL_RANK_RANGE = 110
466
+
467
+ def self.add_write(bin, bytes, ctx)
468
+ if ctx.to_a.empty?
469
+ ret_type = Exp::Type::MAP
470
+ else
471
+ ret_type = ((ctx[0].id & 0x10) == 0) ? Exp::Type::MAP : Exp::Type::LIST
472
+ end
473
+ Exp::Module.new(bin, bytes, ret_type, MODULE | Exp::MODIFY)
474
+ end
475
+
476
+ def self.add_read(bin, bytes, ret_type)
477
+ Exp::Module.new(bin, bytes, ret_type, MODULE)
478
+ end
479
+
480
+ def self.get_value_type(return_type)
481
+ t = return_type & ~CDT::MapReturnType::INVERTED
482
+
483
+ if t <= CDT::MapReturnType::COUNT
484
+ return Exp::Type::INT
485
+ end
486
+
487
+ if t == CDT::MapReturnType::KEY_VALUE
488
+ return Exp::Type::MAP
489
+ end
490
+ return Exp::Type::LIST
491
+ end
492
+ end # class MapExp
493
+ end # module Aerospike
@@ -0,0 +1,56 @@
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 no
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
+ # Expression operations.
20
+ class Exp::Operation
21
+ ##
22
+ # Create operation that performs an expression that writes to a record bin.
23
+ # Requires server version 5.6.0+.
24
+ #
25
+ # @param bin_name name of bin to store expression result
26
+ # @param exp expression to evaluate
27
+ # @param flags expression write flags. See {@link Exp::WriteFlags}
28
+ def self.write(bin_name, exp, flags = Aerospike::Exp::WriteFlags::DEFAULT)
29
+ create_operation(Aerospike::Operation::EXP_MODIFY, bin_name, exp, flags)
30
+ end
31
+
32
+ ##
33
+ # Create operation that performs a read expression.
34
+ # Requires server version 5.6.0+.
35
+ #
36
+ # @param name variable name of read expression result. This name can be used as the
37
+ # bin name when retrieving bin results from the record.
38
+ # @param exp expression to evaluate
39
+ # @param flags expression read flags. See {@link Exp::ExpReadFlags}
40
+ def self.read(name, exp, flags = Aerospike::Exp::ReadFlags::DEFAULT)
41
+ create_operation(Aerospike::Operation::EXP_READ, name, exp, flags)
42
+ end
43
+
44
+ private
45
+
46
+ def self.create_operation(type, name, exp, flags)
47
+ Packer.use do |packer|
48
+ packer.write_array_header(2)
49
+ exp.pack(packer)
50
+ packer.write(flags)
51
+
52
+ return Operation.new(type, name, BytesValue.new(packer.bytes))
53
+ end
54
+ end
55
+ end
56
+ end
@@ -23,10 +23,10 @@ module Aerospike
23
23
  module Features
24
24
 
25
25
  # Server supports List Complex Data Type (CDT)
26
- CDT_LIST = :"cdt-list"
26
+ CDT_LIST = :'cdt-list'
27
27
 
28
28
  # Server supports Map Complex Data Type (CDT)
29
- CDT_MAP = :"cdt-map"
29
+ CDT_MAP = :'cdt-map'
30
30
 
31
31
  # Server supports Float data type
32
32
  FLOAT = :float
@@ -34,16 +34,29 @@ module Aerospike
34
34
  # Server supports geo-spatial data type and indexing
35
35
  GEO = :geo
36
36
 
37
- # Server requires "lut=now" in truncate command (AER-5955)
38
- LUT_NOW = :"lut-now"
37
+ # Server requires 'lut=now' in truncate command (AER-5955)
38
+ LUT_NOW = :'lut-now'
39
39
 
40
- # Server supports the new "peers" protocol for automatic node discovery
40
+ # Server supports the new 'peers' protocol for automatic node discovery
41
41
  PEERS = :peers
42
42
 
43
- # Server supports the "truncate-namespace" command
44
- TRUNCATE_NAMESPACE = :"truncate-namespace"
43
+ # Server supports the 'truncate-namespace' command
44
+ TRUNCATE_NAMESPACE = :'truncate-namespace'
45
45
 
46
- # Server supports the "blob-bits" command
47
- BLOB_BITS = :"blob-bits"
46
+ # Server supports the 'blob-bits' command
47
+ BLOB_BITS = :'blob-bits'
48
+
49
+ # Server supports resumable partition scans
50
+ PARTITION_SCAN = :'pscans'
51
+
52
+ # Server supports the 'query-show' command to check for the
53
+ # progress of the scans and queries
54
+ QUERY_SHOW = :'query-show'
55
+
56
+ # Server supports the batch command for all types of operations, including wrties
57
+ BATCH_ANY = :'batch-any'
58
+
59
+ # Server supports resumable partition queries
60
+ PARTITION_QUERY = :'pquery'
48
61
  end
49
62
  end
@@ -20,7 +20,7 @@
20
20
  module Aerospike
21
21
  class Host
22
22
  module Parse
23
- INTEGER_REGEX = /\A\d+\z/
23
+ INTEGER_REGEX = /\A\d+\z/.freeze
24
24
 
25
25
  class << self
26
26
  ##
@@ -73,4 +73,4 @@ module Aerospike
73
73
  end
74
74
  end
75
75
  end
76
- end
76
+ end
data/lib/aerospike/key.rb CHANGED
@@ -53,15 +53,20 @@ module Aerospike
53
53
 
54
54
  attr_reader :namespace, :set_name, :digest
55
55
 
56
- def initialize(ns, set, val, digest=nil, v1_compatible: self.class.v1_compatible?)
56
+ def initialize(ns, set, val, digest=nil, bval: nil, v1_compatible: self.class.v1_compatible?)
57
57
  @namespace = ns
58
58
  @set_name = set
59
59
  @user_key = Value.of(val)
60
60
  check_key!(@namespace, @set_name, @user_key, !digest.nil?)
61
61
  @digest = digest || compute_digest(v1_compatible)
62
+ @bval = bval
62
63
  end
63
64
 
64
65
 
66
+ def bval
67
+ @bval
68
+ end
69
+
65
70
  def to_s
66
71
  "#{@namespace}:#{@set_name}:#{@user_key}:#{@digest.nil? ? '' : @digest.bytes}"
67
72
  end
@@ -85,6 +90,10 @@ module Aerospike
85
90
  @digest.hash
86
91
  end
87
92
 
93
+ def partition_id
94
+ (@digest[0..3].unpack(Partition::UNPACK_FORMAT)[0] & 0xFFFF) % Node::PARTITIONS
95
+ end
96
+
88
97
  private
89
98
 
90
99
  def valid_key?(value, has_digest)
@@ -30,7 +30,7 @@ module Aerospike
30
30
  def call(node, peers)
31
31
  conn = node.tend_connection
32
32
  if peers.use_peers?
33
- cmds = node.cluster.rack_aware ? CMDS_REBALANCE : CMDS_PEERS
33
+ cmds = node.cluster.rack_aware ? CMDS_REBALANCE : CMDS_PEERS
34
34
  info_map = ::Aerospike::Info.request(conn, *cmds)
35
35
  Verify::PeersGeneration.(node, info_map, peers)
36
36
  Verify::PartitionGeneration.(node, info_map)
@@ -40,4 +40,4 @@ module Aerospike
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -40,4 +40,4 @@ module Aerospike
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -38,4 +38,4 @@ module Aerospike
38
38
  end
39
39
  end
40
40
  end
41
- end
41
+ end
@@ -40,4 +40,4 @@ module Aerospike
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end