aerospike 2.12.0 → 2.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/lib/aerospike.rb +17 -4
  4. data/lib/aerospike/aerospike_exception.rb +7 -1
  5. data/lib/aerospike/atomic/atomic.rb +1 -1
  6. data/lib/aerospike/bin.rb +1 -1
  7. data/lib/aerospike/cdt/bit_operation.rb +376 -0
  8. data/lib/aerospike/cdt/bit_overflow_action.rb +46 -0
  9. data/lib/aerospike/cdt/bit_policy.rb +36 -0
  10. data/lib/aerospike/cdt/bit_resize_flags.rb +44 -0
  11. data/lib/aerospike/cdt/bit_write_flags.rb +51 -0
  12. data/lib/aerospike/cdt/context.rb +113 -0
  13. data/lib/aerospike/cdt/hll_operation.rb +200 -0
  14. data/lib/aerospike/cdt/hll_policy.rb +34 -0
  15. data/lib/aerospike/cdt/hll_write_flags.rb +53 -0
  16. data/lib/aerospike/cdt/list_operation.rb +156 -97
  17. data/lib/aerospike/cdt/list_order.rb +7 -0
  18. data/lib/aerospike/cdt/list_sort_flags.rb +10 -2
  19. data/lib/aerospike/cdt/map_operation.rb +180 -93
  20. data/lib/aerospike/cdt/map_order.rb +4 -4
  21. data/lib/aerospike/cdt/map_policy.rb +1 -1
  22. data/lib/aerospike/cdt/map_return_type.rb +1 -1
  23. data/lib/aerospike/cdt/map_write_mode.rb +1 -1
  24. data/lib/aerospike/client.rb +33 -16
  25. data/lib/aerospike/cluster.rb +139 -17
  26. data/lib/aerospike/cluster/partition.rb +1 -1
  27. data/lib/aerospike/cluster/partition_parser.rb +169 -0
  28. data/lib/aerospike/cluster/rack_parser.rb +117 -0
  29. data/lib/aerospike/command/admin_command.rb +1 -1
  30. data/lib/aerospike/command/batch_direct_command.rb +2 -1
  31. data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
  32. data/lib/aerospike/command/batch_direct_node.rb +3 -3
  33. data/lib/aerospike/command/batch_index_command.rb +1 -0
  34. data/lib/aerospike/command/batch_index_node.rb +2 -2
  35. data/lib/aerospike/command/batch_item.rb +1 -1
  36. data/lib/aerospike/command/command.rb +90 -8
  37. data/lib/aerospike/command/delete_command.rb +5 -1
  38. data/lib/aerospike/command/execute_command.rb +1 -1
  39. data/lib/aerospike/command/exists_command.rb +5 -1
  40. data/lib/aerospike/command/field_type.rb +2 -1
  41. data/lib/aerospike/command/multi_command.rb +49 -2
  42. data/lib/aerospike/command/operate_command.rb +6 -1
  43. data/lib/aerospike/command/read_command.rb +39 -3
  44. data/lib/aerospike/command/read_header_command.rb +5 -1
  45. data/lib/aerospike/command/roles.rb +1 -1
  46. data/lib/aerospike/command/single_command.rb +9 -3
  47. data/lib/aerospike/command/touch_command.rb +39 -2
  48. data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
  49. data/lib/aerospike/command/write_command.rb +5 -1
  50. data/lib/aerospike/connection/create.rb +1 -1
  51. data/lib/aerospike/features.rb +6 -1
  52. data/lib/aerospike/geo_json.rb +1 -1
  53. data/lib/aerospike/host.rb +1 -1
  54. data/lib/aerospike/info.rb +1 -1
  55. data/lib/aerospike/key.rb +1 -1
  56. data/lib/aerospike/language.rb +1 -1
  57. data/lib/aerospike/node.rb +21 -7
  58. data/lib/aerospike/node/rebalance.rb +50 -0
  59. data/lib/aerospike/node/refresh/info.rb +4 -1
  60. data/lib/aerospike/node/refresh/partitions.rb +6 -15
  61. data/lib/aerospike/node/refresh/racks.rb +47 -0
  62. data/lib/aerospike/node/refresh/reset.rb +1 -0
  63. data/lib/aerospike/node/verify/rebalance_generation.rb +43 -0
  64. data/lib/aerospike/node_validator.rb +4 -19
  65. data/lib/aerospike/operation.rb +8 -3
  66. data/lib/aerospike/policy/admin_policy.rb +1 -1
  67. data/lib/aerospike/policy/batch_policy.rb +1 -1
  68. data/lib/aerospike/policy/client_policy.rb +16 -1
  69. data/lib/aerospike/policy/commit_level.rb +1 -1
  70. data/lib/aerospike/policy/consistency_level.rb +1 -1
  71. data/lib/aerospike/policy/generation_policy.rb +1 -1
  72. data/lib/aerospike/policy/operate_policy.rb +1 -1
  73. data/lib/aerospike/policy/policy.rb +19 -2
  74. data/lib/aerospike/policy/priority.rb +1 -1
  75. data/lib/aerospike/policy/query_policy.rb +8 -1
  76. data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
  77. data/lib/aerospike/policy/record_exists_action.rb +1 -1
  78. data/lib/aerospike/policy/replica.rb +45 -0
  79. data/lib/aerospike/policy/scan_policy.rb +8 -1
  80. data/lib/aerospike/policy/write_policy.rb +1 -1
  81. data/lib/aerospike/query/filter.rb +1 -1
  82. data/lib/aerospike/query/query_command.rb +10 -1
  83. data/lib/aerospike/query/recordset.rb +1 -1
  84. data/lib/aerospike/query/scan_command.rb +1 -1
  85. data/lib/aerospike/query/statement.rb +1 -1
  86. data/lib/aerospike/query/stream_command.rb +1 -1
  87. data/lib/aerospike/record.rb +1 -1
  88. data/lib/aerospike/result_code.rb +14 -1
  89. data/lib/aerospike/socket/base.rb +4 -3
  90. data/lib/aerospike/task/execute_task.rb +1 -1
  91. data/lib/aerospike/task/index_task.rb +1 -1
  92. data/lib/aerospike/task/task.rb +1 -1
  93. data/lib/aerospike/task/udf_register_task.rb +1 -1
  94. data/lib/aerospike/task/udf_remove_task.rb +1 -1
  95. data/lib/aerospike/ttl.rb +1 -1
  96. data/lib/aerospike/udf.rb +1 -1
  97. data/lib/aerospike/user_role.rb +1 -1
  98. data/lib/aerospike/utils/buffer.rb +14 -4
  99. data/lib/aerospike/utils/packer.rb +1 -1
  100. data/lib/aerospike/utils/pool.rb +1 -1
  101. data/lib/aerospike/utils/unpacker.rb +3 -3
  102. data/lib/aerospike/value/particle_type.rb +2 -2
  103. data/lib/aerospike/value/value.rb +108 -6
  104. data/lib/aerospike/version.rb +1 -1
  105. metadata +19 -6
  106. data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
  107. data/lib/aerospike/cluster/partition_tokenizer_old.rb +0 -135
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
+ #
5
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
+ # license agreements.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
+ # use this file except in compliance with the License. You may obtain a copy of
10
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ # License for the specific language governing permissions and limitations under
16
+ # the License.
17
+
18
+ require 'base64'
19
+
20
+ module Aerospike
21
+
22
+ class RackParser #:nodoc:
23
+
24
+ attr_accessor :rebalance_generation, :racks
25
+
26
+ REBALANCE_GENERATION = "rebalance-generation"
27
+ RACK_IDS = "rack-ids"
28
+
29
+ def initialize(node, conn)
30
+ @node = node
31
+ @conn = conn
32
+ @racks = nil
33
+ end
34
+
35
+ def update_racks
36
+ # Use low-level info methods and parse byte array directly for maximum performance.
37
+ # Receive format: rack-ids\t
38
+ # <ns1>:<rack-id>...;
39
+ # <ns2>:<rack-id>...; ...
40
+ info_map = Info.request(@conn, REBALANCE_GENERATION, RACK_IDS)
41
+
42
+ @rebalance_generation = info_map[REBALANCE_GENERATION].to_i
43
+
44
+ info = info_map[RACK_IDS]
45
+ if !info || info.length == 0
46
+ raise Aerospike::Exceptions::Connection.new("#{RACK_IDS} response for node #{@node.name} is empty")
47
+ end
48
+
49
+ @buffer = info
50
+ @length = info.length
51
+ @offset = 0
52
+
53
+ while @offset < @length && @buffer[@offset] != '\n'
54
+ namespace = parse_name
55
+ rack_id = parse_rack_id
56
+
57
+ @racks = {} if !@racks
58
+ @racks[namespace] = rack_id
59
+ end
60
+
61
+ @racks
62
+ end
63
+
64
+ private
65
+
66
+ def parse_name
67
+ beginning = @offset
68
+ while @offset < @length
69
+ break if @buffer[@offset] == ':'
70
+ @offset+=1
71
+ end
72
+
73
+ # Parse namespace.
74
+ namespace = @buffer[beginning...@offset].strip
75
+
76
+ if namespace.length <= 0 || namespace.length >= 32
77
+ response = get_truncated_response
78
+ raise Aerospike::Exceptions::Parse.new(
79
+ "Invalid rack namespace #{namespace}. Response=#{response}"
80
+ )
81
+ end
82
+
83
+ @offset+=1
84
+ namespace
85
+ end
86
+
87
+ def parse_rack_id
88
+ beginning = @offset
89
+ while @offset < @length
90
+ break if @buffer[@offset] == ';'
91
+ @offset+=1
92
+ end
93
+
94
+ # Parse rack_id
95
+ rack_id = @buffer[beginning...@offset].strip.to_i
96
+
97
+ if rack_id < 0
98
+ response = get_truncated_response
99
+ raise Aerospike::Exceptions::Parse.new(
100
+ "Invalid rack_id #{rack_id}. Response=#{response}"
101
+ )
102
+ end
103
+
104
+ @offset+=1
105
+ rack_id
106
+ end
107
+
108
+ def get_truncated_response
109
+ max = @length
110
+ @length = max if @length > 200
111
+ @buffer[0...max]
112
+ end
113
+
114
+
115
+ end # class
116
+
117
+ end # module
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -75,6 +75,7 @@ module Aerospike
75
75
  end
76
76
 
77
77
  end_cmd
78
+ mark_compressed(@policy)
78
79
  end
79
80
 
80
81
  # Parse all results in the batch. Add records to shared list.
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -24,8 +24,8 @@ module Aerospike
24
24
  attr_accessor :node
25
25
  attr_accessor :batch_namespaces
26
26
 
27
- def self.generate_list(cluster, keys)
28
- keys.group_by { |key| cluster.get_node_for_key(key) }
27
+ def self.generate_list(cluster, replica_policy, keys)
28
+ keys.group_by { |key| cluster.get_node_for_key(replica_policy, key) }
29
29
  .map { |node, keys_for_node| BatchDirectNode.new(node, keys_for_node) }
30
30
  end
31
31
 
@@ -98,6 +98,7 @@ module Aerospike
98
98
  end
99
99
  end
100
100
  end_cmd
101
+ mark_compressed(@policy)
101
102
  end
102
103
 
103
104
  # Parse all results in the batch. Add records to shared list.
@@ -22,9 +22,9 @@ module Aerospike
22
22
  attr_accessor :node
23
23
  attr_accessor :keys_by_idx
24
24
 
25
- def self.generate_list(cluster, keys)
25
+ def self.generate_list(cluster, replica_policy, keys)
26
26
  keys.each_with_index
27
- .group_by { |key, _| cluster.get_node_for_key(key) }
27
+ .group_by { |key, _| cluster.get_node_for_key(replica_policy, key) }
28
28
  .map { |node, keys_with_idx| BatchIndexNode.new(node, keys_with_idx) }
29
29
  end
30
30
 
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -16,6 +16,7 @@
16
16
  # the License.
17
17
 
18
18
  require 'time'
19
+ require 'zlib'
19
20
 
20
21
  require 'msgpack'
21
22
  require 'aerospike/result_code'
@@ -42,6 +43,9 @@ module Aerospike
42
43
  # Involve all replicas in read operation.
43
44
  INFO1_CONSISTENCY_ALL = Integer(1 << 6)
44
45
 
46
+ # Tell server to compress it's response.
47
+ INFO1_COMPRESS_RESPONSE = (1 << 7)
48
+
45
49
  # Create or update record
46
50
  INFO2_WRITE = Integer(1 << 0)
47
51
  # Fling a record into the belly of Moloch.
@@ -55,6 +59,9 @@ module Aerospike
55
59
  # Create only. Fail if record already exists.
56
60
  INFO2_CREATE_ONLY = Integer(1 << 5)
57
61
 
62
+ # Return a result for every operation.
63
+ INFO2_RESPOND_ALL_OPS = Integer(1 << 7)
64
+
58
65
  # This is the last of a multi-part message.
59
66
  INFO3_LAST = Integer(1 << 0)
60
67
  # Commit to master only before declaring success.
@@ -72,17 +79,24 @@ module Aerospike
72
79
  OPERATION_HEADER_SIZE = 8
73
80
  MSG_REMAINING_HEADER_SIZE = 22
74
81
  DIGEST_SIZE = 20
82
+ COMPRESS_THRESHOLD = 128
75
83
  CL_MSG_VERSION = 2
76
84
  AS_MSG_TYPE = 3
85
+ AS_MSG_TYPE_COMPRESSED = 4
77
86
 
78
87
  class Command #:nodoc:
79
88
 
80
- def initialize(node)
89
+ def initialize(node=nil)
81
90
  @data_offset = 0
82
91
  @data_buffer = nil
83
92
 
84
93
  @node = node
85
94
 
95
+ @compress = false
96
+
97
+ # will add before use
98
+ @sequence = Atomic.new(-1)
99
+
86
100
  self
87
101
  end
88
102
 
@@ -115,6 +129,7 @@ module Aerospike
115
129
  end
116
130
 
117
131
  end_cmd
132
+ mark_compressed(policy)
118
133
  end
119
134
 
120
135
  # Writes the command for delete operations
@@ -242,10 +257,12 @@ module Aerospike
242
257
  read_attr = 0
243
258
  write_attr = 0
244
259
  read_header = false
260
+ record_bin_multiplicity = policy.record_bin_multiplicity == RecordBinMultiplicity::ARRAY
245
261
 
246
262
  operations.each do |operation|
247
263
  case operation.op_type
248
- when Aerospike::Operation::READ
264
+ when Aerospike::Operation::READ, Aerospike::Operation::CDT_READ,
265
+ Aerospike::Operation::HLL_READ, Aerospike::Operation::BIT_READ
249
266
  read_attr |= INFO1_READ
250
267
 
251
268
  # Read all bins if no bin is specified.
@@ -259,17 +276,22 @@ module Aerospike
259
276
  read_attr |= INFO1_READ
260
277
  read_header = true
261
278
 
262
- when Aerospike::Operation::CDT_READ
263
- read_attr |= INFO1_READ
264
-
265
279
  else
266
280
  write_attr = INFO2_WRITE
267
281
  end
268
282
 
283
+ if [Aerospike::Operation::HLL_MODIFY, Aerospike::Operation::HLL_READ,
284
+ Aerospike::Operation::BIT_MODIFY, Aerospike::Operation::BIT_READ].include?(operation.op_type)
285
+ record_bin_multiplicity = true
286
+ end
287
+
269
288
  estimate_operation_size_for_operation(operation)
270
289
  end
271
290
  size_buffer
272
291
 
292
+
293
+ write_attr |= INFO2_RESPOND_ALL_OPS if write_attr != 0 && record_bin_multiplicity
294
+
273
295
  if write_attr != 0
274
296
  write_header_with_policy(policy, read_attr, write_attr, field_count, operations.length)
275
297
  else
@@ -285,6 +307,7 @@ module Aerospike
285
307
  write_operation_for_bin(nil, Aerospike::Operation::READ) if read_header
286
308
 
287
309
  end_cmd
310
+ mark_compressed(policy)
288
311
  end
289
312
 
290
313
  def set_udf(policy, key, package_name, function_name, args)
@@ -307,6 +330,7 @@ module Aerospike
307
330
  write_field_bytes(arg_bytes, Aerospike::FieldType::UDF_ARGLIST)
308
331
 
309
332
  end_cmd
333
+ mark_compressed(policy)
310
334
  end
311
335
 
312
336
  def set_scan(policy, namespace, set_name, bin_names)
@@ -324,6 +348,11 @@ module Aerospike
324
348
  field_count += 1
325
349
  end
326
350
 
351
+ if policy.records_per_second > 0
352
+ @data_offset += 4 + FIELD_HEADER_SIZE
353
+ field_count += 1
354
+ end
355
+
327
356
  predexp_size = estimate_predexp(policy.predexp)
328
357
  field_count += 1 if predexp_size > 0
329
358
 
@@ -363,6 +392,10 @@ module Aerospike
363
392
  write_field_string(set_name, Aerospike::FieldType::TABLE)
364
393
  end
365
394
 
395
+ if policy.records_per_second > 0
396
+ write_field_int(policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
397
+ end
398
+
366
399
  write_predexp(policy.predexp, predexp_size)
367
400
 
368
401
  write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
@@ -410,6 +443,7 @@ module Aerospike
410
443
  break if @policy.timeout > 0 && Time.now > limit
411
444
 
412
445
  begin
446
+ @node = get_node
413
447
  @conn = @node.get_connection(@policy.timeout)
414
448
  rescue => e
415
449
  # Socket connection error has occurred. Decrease health and retry.
@@ -566,6 +600,7 @@ module Aerospike
566
600
  # Generic header write.
567
601
  def write_header(policy, read_attr, write_attr, field_count, operation_count)
568
602
  read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
603
+ read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
569
604
 
570
605
  # Write all header data except total size which must be written last.
571
606
  @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message heade.length.
@@ -615,6 +650,7 @@ module Aerospike
615
650
  info_attr |= INFO3_COMMIT_MASTER if policy.commit_level == Aerospike::CommitLevel::COMMIT_MASTER
616
651
  read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
617
652
  write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
653
+ read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
618
654
 
619
655
  # Write all header data except total size which must be written last.
620
656
  @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message heade.length.
@@ -746,15 +782,19 @@ module Aerospike
746
782
  @data_offset += len
747
783
  end
748
784
 
785
+ def write_field_int(i, ftype)
786
+ @data_buffer.write_int32(i, @data_offset+FIELD_HEADER_SIZE)
787
+ write_field_header(4, ftype)
788
+ @data_offset += 4
789
+ end
790
+
749
791
  def write_field_bytes(bytes, ftype)
750
792
  @data_buffer.write_binary(bytes, @data_offset+FIELD_HEADER_SIZE)
751
-
752
793
  write_field_header(bytes.bytesize, ftype)
753
794
  @data_offset += bytes.bytesize
754
795
  end
755
796
 
756
797
  def write_field_header(size, ftype)
757
- # Buffer.Int32ToBytes(size+1), @data_buffer, @data_offset
758
798
  @data_buffer.write_int32(size+1, @data_offset)
759
799
  @data_offset += 4
760
800
  @data_buffer.write_byte(ftype, @data_offset)
@@ -793,6 +833,48 @@ module Aerospike
793
833
  @data_buffer.write_int64(size, 0)
794
834
  end
795
835
 
836
+ def use_compression?
837
+ @compress
838
+ end
839
+
840
+ def compress_buffer
841
+ if @data_offset > COMPRESS_THRESHOLD
842
+ compressed = Zlib::deflate(@data_buffer.buf, Zlib::DEFAULT_COMPRESSION)
843
+
844
+ # write original size as header
845
+ proto_s = "%08d" % 0
846
+ proto_s[0, 8] = [@data_offset].pack('q>')
847
+ compressed.prepend(proto_s)
848
+
849
+ # write proto
850
+ proto = (compressed.size+8) | Integer(CL_MSG_VERSION << 56) | Integer(AS_MSG_TYPE << 48)
851
+ proto_s = "%08d" % 0
852
+ proto_s[0, 8] = [proto].pack('q>')
853
+ compressed.prepend(proto_s)
854
+
855
+ @data_buffer = Buffer.new(-1, compressed)
856
+ @data_offset = @data_buffer.size
857
+ end
858
+ end
859
+
860
+ # isCompressed returns the length of the compressed buffer.
861
+ # If the buffer is not compressed, the result will be -1
862
+ def compressed_size
863
+ # A number of these are commented out because we just don't care enough to read
864
+ # that section of the header. If we do care, uncomment and check!
865
+ proto = @data_buffer.read_int64(0)
866
+ size = proto & 0xFFFFFFFFFFFF
867
+ msg_type = (proto >> 48) & 0xFF
868
+
869
+ return nil if msg_type != AS_MSG_TYPE_COMPRESSED
870
+
871
+ size
872
+ end
873
+
874
+ def mark_compressed(policy)
875
+ @compress = policy.use_compression
876
+ end
877
+
796
878
  end # class
797
879
 
798
880
  end # module
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.master_node(@partition)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_delete(@policy, @key)
38
42
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.