aerospike 2.19.0 → 2.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|