aerospike 2.19.0 → 2.20.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/lib/aerospike/client.rb +10 -5
- data/lib/aerospike/cluster.rb +21 -0
- data/lib/aerospike/command/batch_index_command.rb +4 -8
- data/lib/aerospike/command/batch_index_exists_command.rb +1 -1
- data/lib/aerospike/command/command.rb +29 -12
- data/lib/aerospike/command/field_type.rb +1 -0
- data/lib/aerospike/command/multi_command.rb +17 -0
- data/lib/aerospike/query/query_command.rb +21 -11
- data/lib/aerospike/query/scan_command.rb +3 -2
- data/lib/aerospike/query/stream_command.rb +3 -0
- data/lib/aerospike/utils/buffer.rb +10 -0
- data/lib/aerospike/value/particle_type.rb +1 -12
- data/lib/aerospike/value/value.rb +9 -4
- data/lib/aerospike/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bed472fc5bda556a4f67f2d6e4e0ee8a82188253b34e0bfab3a0b05be3526d2e
|
4
|
+
data.tar.gz: 4a11f36509d86792412e764ef978ec6e27753eab2a96e65353b73786ea383591
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa02cbf6bc8e6065e80849e5dcbe71d91550eb549c77af53c761df2e969d7f3135ea3641dcc8af28bd98d5f3e46ab868e61f4e61023c70f0a400e99c93747a00
|
7
|
+
data.tar.gz: 47f9d0da4d7099b2e96992012deb79292c4de7d8bbd8fa9ca3a362dc5aa126841887d3eef8f0f0f15e176190a729dde8377f486f3c0ef357b312ab43569b31ce
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [2.20.0] - 2020-11-08
|
6
|
+
|
7
|
+
Notice: This version of the client only supports Aerospike Server v4.9 and later. Some features will work for the older server versions, but they are not tested, nor officially supported.
|
8
|
+
|
9
|
+
* **New Features**
|
10
|
+
* [CLIENT-1467] Support native Boolean type for server v5.6+.
|
11
|
+
|
12
|
+
* **Improvements**
|
13
|
+
* Add basic support for server v4.9+ scan/queries.
|
14
|
+
* Don't check for key equality in Batch command results.
|
15
|
+
|
5
16
|
## [2.19.0] - 2020-02-09
|
6
17
|
|
7
18
|
* **Improvements**
|
data/lib/aerospike/client.rb
CHANGED
@@ -543,10 +543,11 @@ module Aerospike
|
|
543
543
|
|
544
544
|
# Use a thread per node
|
545
545
|
nodes.each do |node|
|
546
|
+
partitions = node.cluster.node_partitions(node, statement.namespace)
|
546
547
|
Thread.new do
|
547
548
|
Thread.current.abort_on_exception = true
|
548
549
|
begin
|
549
|
-
command = QueryCommand.new(node, policy, statement, nil)
|
550
|
+
command = QueryCommand.new(node, policy, statement, nil, partitions)
|
550
551
|
execute_command(command)
|
551
552
|
rescue => e
|
552
553
|
Aerospike.logger.error(e)
|
@@ -644,9 +645,10 @@ module Aerospike
|
|
644
645
|
if policy.concurrent_nodes
|
645
646
|
# Use a thread per node
|
646
647
|
nodes.each do |node|
|
648
|
+
partitions = node.cluster.node_partitions(node, namespace)
|
647
649
|
Thread.new do
|
648
650
|
Thread.current.abort_on_exception = true
|
649
|
-
command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset)
|
651
|
+
command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset, partitions)
|
650
652
|
begin
|
651
653
|
execute_command(command)
|
652
654
|
rescue => e
|
@@ -661,7 +663,8 @@ module Aerospike
|
|
661
663
|
Thread.new do
|
662
664
|
Thread.current.abort_on_exception = true
|
663
665
|
nodes.each do |node|
|
664
|
-
|
666
|
+
partitions = node.cluster.node_partitions(node, namespace)
|
667
|
+
command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset, partitions)
|
665
668
|
begin
|
666
669
|
execute_command(command)
|
667
670
|
rescue => e
|
@@ -694,9 +697,10 @@ module Aerospike
|
|
694
697
|
|
695
698
|
recordset = Recordset.new(policy.record_queue_size, 1, :scan)
|
696
699
|
|
700
|
+
partitions = node.cluster.node_partitions(node, namespace)
|
697
701
|
Thread.new do
|
698
702
|
Thread.current.abort_on_exception = true
|
699
|
-
command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset)
|
703
|
+
command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset, partitions)
|
700
704
|
begin
|
701
705
|
execute_command(command)
|
702
706
|
rescue => e
|
@@ -734,9 +738,10 @@ module Aerospike
|
|
734
738
|
|
735
739
|
# Use a thread per node
|
736
740
|
nodes.each do |node|
|
741
|
+
partitions = node.cluster.node_partitions(node, statement.namespace)
|
737
742
|
Thread.new do
|
738
743
|
Thread.current.abort_on_exception = true
|
739
|
-
command = QueryCommand.new(node, new_policy, statement, recordset)
|
744
|
+
command = QueryCommand.new(node, new_policy, statement, recordset, partitions)
|
740
745
|
begin
|
741
746
|
execute_command(command)
|
742
747
|
rescue => e
|
data/lib/aerospike/cluster.rb
CHANGED
@@ -230,6 +230,27 @@ module Aerospike
|
|
230
230
|
batch_read_node(partition, replica_policy)
|
231
231
|
end
|
232
232
|
|
233
|
+
# Returns partitions pertaining to a node
|
234
|
+
def node_partitions(node, namespace)
|
235
|
+
res = []
|
236
|
+
|
237
|
+
partition_map = partitions
|
238
|
+
replica_array = partition_map[namespace]
|
239
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
|
240
|
+
|
241
|
+
node_array = (replica_array.get)[0]
|
242
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !node_array
|
243
|
+
|
244
|
+
|
245
|
+
pid = 0
|
246
|
+
for tnode in node_array.get
|
247
|
+
res << pid if node == tnode
|
248
|
+
pid+=1
|
249
|
+
end
|
250
|
+
|
251
|
+
res
|
252
|
+
end
|
253
|
+
|
233
254
|
# Returns a random node on the cluster
|
234
255
|
def random_node
|
235
256
|
# Must copy array reference for copy on write semantics to work.
|
@@ -110,16 +110,12 @@ module Aerospike
|
|
110
110
|
field_count = @data_buffer.read_int16(18)
|
111
111
|
op_count = @data_buffer.read_int16(20)
|
112
112
|
|
113
|
-
|
113
|
+
skip_key(field_count)
|
114
114
|
req_key = batch.key_for_index(batch_index)
|
115
115
|
|
116
|
-
if
|
117
|
-
|
118
|
-
|
119
|
-
results[batch_index] = record
|
120
|
-
end
|
121
|
-
else
|
122
|
-
Aerospike.logger.warn("Unexpected batch key returned: #{key}")
|
116
|
+
if result_code == 0
|
117
|
+
record = parse_record(req_key, op_count, generation, expiration)
|
118
|
+
results[batch_index] = record
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
@@ -66,6 +66,8 @@ module Aerospike
|
|
66
66
|
INFO3_LAST = Integer(1 << 0)
|
67
67
|
# Commit to master only before declaring success.
|
68
68
|
INFO3_COMMIT_MASTER = Integer(1 << 1)
|
69
|
+
# Partition is complete response in scan.
|
70
|
+
INFO3_PARTITION_DONE = Integer(1 << 2)
|
69
71
|
# Update only. Merge bins.
|
70
72
|
INFO3_UPDATE_ONLY = Integer(1 << 3)
|
71
73
|
|
@@ -333,7 +335,7 @@ module Aerospike
|
|
333
335
|
mark_compressed(policy)
|
334
336
|
end
|
335
337
|
|
336
|
-
def set_scan(policy, namespace, set_name, bin_names)
|
338
|
+
def set_scan(policy, namespace, set_name, bin_names, partitions)
|
337
339
|
# Estimate buffer size
|
338
340
|
begin_cmd
|
339
341
|
field_count = 0
|
@@ -357,7 +359,10 @@ module Aerospike
|
|
357
359
|
field_count += 1 if predexp_size > 0
|
358
360
|
|
359
361
|
# Estimate scan options size.
|
360
|
-
@data_offset += 2 + FIELD_HEADER_SIZE
|
362
|
+
# @data_offset += 2 + FIELD_HEADER_SIZE
|
363
|
+
# field_count += 1
|
364
|
+
|
365
|
+
@data_offset += partitions.length * 2 + FIELD_HEADER_SIZE
|
361
366
|
field_count += 1
|
362
367
|
|
363
368
|
# Estimate scan timeout size.
|
@@ -392,24 +397,30 @@ module Aerospike
|
|
392
397
|
write_field_string(set_name, Aerospike::FieldType::TABLE)
|
393
398
|
end
|
394
399
|
|
400
|
+
write_field_header(partitions.length * 2, Aerospike::FieldType::PID_ARRAY)
|
401
|
+
for pid in partitions
|
402
|
+
@data_buffer.write_uint16_little_endian(pid, @data_offset)
|
403
|
+
@data_offset += 2
|
404
|
+
end
|
405
|
+
|
395
406
|
if policy.records_per_second > 0
|
396
407
|
write_field_int(policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
|
397
408
|
end
|
398
409
|
|
399
410
|
write_predexp(policy.predexp, predexp_size)
|
400
411
|
|
401
|
-
write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
412
|
+
# write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
402
413
|
|
403
|
-
priority = policy.priority & 0xFF
|
404
|
-
priority <<= 4
|
405
|
-
if policy.fail_on_cluster_change
|
406
|
-
|
407
|
-
end
|
414
|
+
# priority = policy.priority & 0xFF
|
415
|
+
# priority <<= 4
|
416
|
+
# if policy.fail_on_cluster_change
|
417
|
+
# priority |= 0x08
|
418
|
+
# end
|
408
419
|
|
409
|
-
@data_buffer.write_byte(priority, @data_offset)
|
410
|
-
@data_offset += 1
|
411
|
-
@data_buffer.write_byte(policy.scan_percent.to_i.ord, @data_offset)
|
412
|
-
@data_offset += 1
|
420
|
+
# @data_buffer.write_byte(priority, @data_offset)
|
421
|
+
# @data_offset += 1
|
422
|
+
# @data_buffer.write_byte(policy.scan_percent.to_i.ord, @data_offset)
|
423
|
+
# @data_offset += 1
|
413
424
|
|
414
425
|
write_field_header(4, Aerospike::FieldType::SCAN_TIMEOUT)
|
415
426
|
@data_buffer.write_uint32(policy.socket_timeout.to_i, @data_offset)
|
@@ -786,6 +797,12 @@ module Aerospike
|
|
786
797
|
@data_offset += len
|
787
798
|
end
|
788
799
|
|
800
|
+
def write_u16_little_endian(i, ftype)
|
801
|
+
@data_buffer.write_uint16_little_endian(i, @data_offset+FIELD_HEADER_SIZE)
|
802
|
+
write_field_header(2, ftype)
|
803
|
+
@data_offset += 2
|
804
|
+
end
|
805
|
+
|
789
806
|
def write_field_int(i, ftype)
|
790
807
|
@data_buffer.write_int32(i, @data_offset+FIELD_HEADER_SIZE)
|
791
808
|
write_field_header(4, ftype)
|
@@ -150,6 +150,23 @@ module Aerospike
|
|
150
150
|
Aerospike::Key.new(namespace, set_name, user_key, digest)
|
151
151
|
end
|
152
152
|
|
153
|
+
def skip_key(field_count)
|
154
|
+
# in Stream queries, there are no keys
|
155
|
+
return unless field_count > 0
|
156
|
+
|
157
|
+
i = 0
|
158
|
+
while i < field_count
|
159
|
+
read_bytes(4)
|
160
|
+
|
161
|
+
fieldlen = @data_buffer.read_int32(0)
|
162
|
+
read_bytes(fieldlen)
|
163
|
+
|
164
|
+
i = i.succ
|
165
|
+
end
|
166
|
+
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
153
170
|
# Parses the given byte buffer and populate the result object.
|
154
171
|
# Returns the number of bytes that were parsed from the given buffer.
|
155
172
|
def parse_record(key, op_count, generation, expiration)
|
@@ -23,12 +23,13 @@ module Aerospike
|
|
23
23
|
|
24
24
|
class QueryCommand < StreamCommand #:nodoc:
|
25
25
|
|
26
|
-
def initialize(node, policy, statement, recordset)
|
26
|
+
def initialize(node, policy, statement, recordset, partitions)
|
27
27
|
super(node)
|
28
28
|
|
29
29
|
@policy = policy
|
30
30
|
@statement = statement
|
31
31
|
@recordset = recordset
|
32
|
+
@partitions = partitions
|
32
33
|
end
|
33
34
|
|
34
35
|
def write_buffer
|
@@ -81,7 +82,10 @@ module Aerospike
|
|
81
82
|
@data_offset += binNameSize
|
82
83
|
fieldCount+=1
|
83
84
|
end
|
84
|
-
else
|
85
|
+
else
|
86
|
+
@data_offset += @partitions.length * 2 + FIELD_HEADER_SIZE
|
87
|
+
fieldCount += 1
|
88
|
+
|
85
89
|
if @policy.records_per_second > 0
|
86
90
|
@data_offset += 4 + FIELD_HEADER_SIZE
|
87
91
|
fieldCount += 1
|
@@ -89,8 +93,8 @@ module Aerospike
|
|
89
93
|
|
90
94
|
# Calling query with no filters is more efficiently handled by a primary index scan.
|
91
95
|
# Estimate scan options size.
|
92
|
-
@data_offset += (2 + FIELD_HEADER_SIZE)
|
93
|
-
fieldCount+=1
|
96
|
+
# @data_offset += (2 + FIELD_HEADER_SIZE)
|
97
|
+
# fieldCount+=1
|
94
98
|
end
|
95
99
|
|
96
100
|
@statement.set_task_id
|
@@ -177,18 +181,24 @@ module Aerospike
|
|
177
181
|
end
|
178
182
|
end
|
179
183
|
else
|
184
|
+
write_field_header(@partitions.length * 2, Aerospike::FieldType::PID_ARRAY)
|
185
|
+
for pid in @partitions
|
186
|
+
@data_buffer.write_uint16_little_endian(pid, @data_offset)
|
187
|
+
@data_offset += 2
|
188
|
+
end
|
189
|
+
|
180
190
|
if @policy.records_per_second > 0
|
181
191
|
write_field_int(@policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
|
182
192
|
end
|
183
193
|
|
184
194
|
# Calling query with no filters is more efficiently handled by a primary index scan.
|
185
|
-
write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
186
|
-
priority = @policy.priority.ord
|
187
|
-
priority = priority << 4
|
188
|
-
@data_buffer.write_byte(priority, @data_offset)
|
189
|
-
@data_offset+=1
|
190
|
-
@data_buffer.write_byte(100.ord, @data_offset)
|
191
|
-
@data_offset+=1
|
195
|
+
# write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
196
|
+
# priority = @policy.priority.ord
|
197
|
+
# priority = priority << 4
|
198
|
+
# @data_buffer.write_byte(priority, @data_offset)
|
199
|
+
# @data_offset+=1
|
200
|
+
# @data_buffer.write_byte(100.ord, @data_offset)
|
201
|
+
# @data_offset+=1
|
192
202
|
end
|
193
203
|
|
194
204
|
write_field_header(8, Aerospike::FieldType::TRAN_ID)
|
@@ -23,7 +23,7 @@ module Aerospike
|
|
23
23
|
|
24
24
|
class ScanCommand < StreamCommand #:nodoc:
|
25
25
|
|
26
|
-
def initialize(node, policy, namespace, set_name, bin_names, recordset)
|
26
|
+
def initialize(node, policy, namespace, set_name, bin_names, recordset, partitions)
|
27
27
|
super(node)
|
28
28
|
|
29
29
|
@policy = policy
|
@@ -31,10 +31,11 @@ module Aerospike
|
|
31
31
|
@set_name = set_name
|
32
32
|
@bin_names = bin_names
|
33
33
|
@recordset = recordset
|
34
|
+
@partitions = partitions
|
34
35
|
end
|
35
36
|
|
36
37
|
def write_buffer
|
37
|
-
set_scan(@policy, @namespace, @set_name, @bin_names)
|
38
|
+
set_scan(@policy, @namespace, @set_name, @bin_names, @partitions)
|
38
39
|
end
|
39
40
|
|
40
41
|
end # class
|
@@ -58,6 +58,9 @@ module Aerospike
|
|
58
58
|
op_count = @data_buffer.read_int16(20)
|
59
59
|
key = parse_key(field_count)
|
60
60
|
|
61
|
+
# If cmd is the end marker of the response, do not proceed further
|
62
|
+
return true if (info3 & INFO3_PARTITION_DONE) != 0
|
63
|
+
|
61
64
|
if result_code == 0
|
62
65
|
if @recordset.active?
|
63
66
|
@recordset.records.enq(parse_record(key, op_count, generation, expiration))
|
@@ -33,6 +33,7 @@ module Aerospike
|
|
33
33
|
|
34
34
|
INT16 = 's>'
|
35
35
|
UINT16 = 'n'
|
36
|
+
UINT16LE = 'v'
|
36
37
|
INT32 = 'l>'
|
37
38
|
UINT32 = 'N'
|
38
39
|
INT64 = 'q>'
|
@@ -92,6 +93,11 @@ module Aerospike
|
|
92
93
|
2
|
93
94
|
end
|
94
95
|
|
96
|
+
def write_uint16_little_endian(i, offset)
|
97
|
+
@buf[offset, 2] = [i].pack(UINT16LE)
|
98
|
+
2
|
99
|
+
end
|
100
|
+
|
95
101
|
def write_int32(i, offset)
|
96
102
|
@buf[offset, 4] = [i].pack(INT32)
|
97
103
|
4
|
@@ -156,6 +162,10 @@ module Aerospike
|
|
156
162
|
vals.unpack(DOUBLE)[0]
|
157
163
|
end
|
158
164
|
|
165
|
+
def read_bool(offset, length)
|
166
|
+
length <= 0 ? false : @buf[offset].ord != 0
|
167
|
+
end
|
168
|
+
|
159
169
|
def to_s
|
160
170
|
@buf[0..@slice_end-1]
|
161
171
|
end
|
@@ -23,19 +23,8 @@ module Aerospike
|
|
23
23
|
DOUBLE = 2
|
24
24
|
STRING = 3
|
25
25
|
BLOB = 4
|
26
|
-
#TIMESTAMP = 5
|
27
|
-
#DIGEST = 6
|
28
|
-
#JBLOB = 7
|
29
|
-
#CSHARP_BLOB = 8
|
30
|
-
#PYTHON_BLOB = 9
|
31
26
|
RUBY_BLOB = 10
|
32
|
-
|
33
|
-
#ERLANG_BLOB = 12
|
34
|
-
#SEGMENT_POINTER = 13
|
35
|
-
#RTA_LIST = 14
|
36
|
-
#RTA_DICT = 15
|
37
|
-
#RTA_APPEND_DICT = 16
|
38
|
-
#RTA_APPEND_LIST = 17
|
27
|
+
BOOL = 17
|
39
28
|
HLL = 18
|
40
29
|
MAP = 19
|
41
30
|
LIST = 20
|
@@ -606,6 +606,9 @@ module Aerospike
|
|
606
606
|
when Aerospike::ParticleType::DOUBLE
|
607
607
|
buf.read_double(offset)
|
608
608
|
|
609
|
+
when Aerospike::ParticleType::BOOL
|
610
|
+
buf.read_bool(offset, length)
|
611
|
+
|
609
612
|
when Aerospike::ParticleType::BLOB
|
610
613
|
buf.read(offset,length)
|
611
614
|
|
@@ -658,7 +661,7 @@ module Aerospike
|
|
658
661
|
#######################################
|
659
662
|
|
660
663
|
# Boolean value.
|
661
|
-
#
|
664
|
+
# Supported by Aerospike server 5.6+ only.
|
662
665
|
class BoolValue < Value #:nodoc:
|
663
666
|
|
664
667
|
def initialize(val)
|
@@ -671,7 +674,9 @@ module Aerospike
|
|
671
674
|
end
|
672
675
|
|
673
676
|
def write(buffer, offset)
|
674
|
-
|
677
|
+
val = @value ? 1 : 0
|
678
|
+
buffer.write_byte(val.ord, offset)
|
679
|
+
1
|
675
680
|
end
|
676
681
|
|
677
682
|
def pack(packer)
|
@@ -679,7 +684,7 @@ module Aerospike
|
|
679
684
|
end
|
680
685
|
|
681
686
|
def type
|
682
|
-
|
687
|
+
Aerospike::ParticleType::BOOL
|
683
688
|
end
|
684
689
|
|
685
690
|
def get
|
@@ -687,7 +692,7 @@ module Aerospike
|
|
687
692
|
end
|
688
693
|
|
689
694
|
def to_bytes
|
690
|
-
|
695
|
+
@value.ord
|
691
696
|
end
|
692
697
|
|
693
698
|
def to_s
|
data/lib/aerospike/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aerospike
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khosrow Afroozeh
|
8
8
|
- Jan Hecking
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|
@@ -210,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
210
|
version: '0'
|
211
211
|
requirements: []
|
212
212
|
rubygems_version: 3.1.2
|
213
|
-
signing_key:
|
213
|
+
signing_key:
|
214
214
|
specification_version: 4
|
215
215
|
summary: An Aerospike driver for Ruby.
|
216
216
|
test_files: []
|