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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85cdd4e1a2cbb3572cf4c84715a6a43e768e5b8b4b3adc583d45dd41280b9c31
4
- data.tar.gz: faa4ae8908d9fca3798b59053a0753bf9df740ff006d6bdccaf39b45fd4b11d7
3
+ metadata.gz: bed472fc5bda556a4f67f2d6e4e0ee8a82188253b34e0bfab3a0b05be3526d2e
4
+ data.tar.gz: 4a11f36509d86792412e764ef978ec6e27753eab2a96e65353b73786ea383591
5
5
  SHA512:
6
- metadata.gz: 1137414c6f8d465650d88d3169710f4c860ce1938acc24998cbdcd33abed486b238f4ce8a3aee92158a610df99db756311d5aba6617bc464db81268e41529cf6
7
- data.tar.gz: 7f9e276d0d4aab9843312cb3054305a82b4b59691473e869ad1fcefb1eaacb6ee19c46c2bdacd0cc081650b474a426a0dea845c1e678e23967b66ab34294a5ff
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**
@@ -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
- command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset)
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
@@ -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
- key = parse_key(field_count)
113
+ skip_key(field_count)
114
114
  req_key = batch.key_for_index(batch_index)
115
115
 
116
- if key.digest == req_key.digest
117
- if result_code == 0
118
- record = parse_record(req_key, op_count, generation, expiration)
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
 
@@ -36,7 +36,7 @@ module Aerospike
36
36
  raise Aerospike::Exceptions::Parse.new('Received bins that were not requested!')
37
37
  end
38
38
 
39
- parse_key(field_count)
39
+ skip_key(field_count)
40
40
  results[batch_index] = (result_code == 0)
41
41
  end
42
42
 
@@ -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
- priority |= 0x08
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)
@@ -32,6 +32,7 @@ module Aerospike
32
32
  SCAN_OPTIONS = 8
33
33
  SCAN_TIMEOUT = 9
34
34
  RECORDS_PER_SECOND = 10
35
+ PID_ARRAY = 11
35
36
  INDEX_NAME = 21
36
37
  INDEX_RANGE = 22
37
38
  INDEX_FILTER = 23
@@ -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
- #PHP_BLOB = 11
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
- # This is private, and only used internally for bitwise CDTs
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
- raise Exception.new("Unreachable")
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
- raise Exception.new("Unreachable")
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
- raise Exception.new("Unreachable")
695
+ @value.ord
691
696
  end
692
697
 
693
698
  def to_s
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Aerospike
3
- VERSION = "2.19.0"
3
+ VERSION = "2.20.0"
4
4
  end
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.19.0
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-02-09 00:00:00.000000000 Z
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: []