aerospike 2.29.0 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5f1927589fab415975f46da19cfc0de4dc00285abe0627f0472d1e8aa27f5c9
4
- data.tar.gz: e8245b120f0f78882e6dba592169434372eaa99032b6542167c7a46296c2bff9
3
+ metadata.gz: 89cd439991384bc1b01465f9c28e9be14f9cb31ba283801ba6f3297eea240015
4
+ data.tar.gz: 6eab65e105f999420692a1757dcaaae9908384851e2f43fe49f6e805be2a3bf7
5
5
  SHA512:
6
- metadata.gz: 3915a6e8d1c82ddf1bdf80b66dcea019270f057b166071a24c1c52419afe9d69aeb97b10210fea58abd011ed4ddef89466823a06fbb807290899f010465314f2
7
- data.tar.gz: 54c1776cece8e96ec07c75d0860aa2047f096352b2e329785e29c8317d4df7b856388d8fe4aeb506774fadc4fdee54f5e0eae7696ff294189ad9e54b7fe13c7a
6
+ metadata.gz: 984c705a6d1604c95ec428f30a05e1f7385d935aaee6d7acab50fb604ff3718836a6184af107e6e842377e177a4bbac46f28954a49d86fa97b9755ef290ee212
7
+ data.tar.gz: fc47757f4a1c55d25c56fba9d663e93dcc81a4c6d0c0d6e691d2d8d80722a32e9901f09415b1958a294ba45fd8dae9aa6d2b433fcb77e96bd957b6bf00fc4a0c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [3.0.0] 2023-12-15
6
+ Notice: This version of the client only supports Aerospike Server v6.0 and later. Some features will work for the older server versions.
7
+ - **new_features**
8
+ - [CLIENT-2575] - Support Exp.recordSize().
9
+ - [CLIENT-2621] - Support persistent map indexes.
10
+
11
+ - **improvements**
12
+ - [CLIENT-2590] - Required Updates Following Server-Side Changes: SINDEX Support for 'Blob' Type Elements.
13
+
5
14
  ## [2.29.0] 2023-08-24
6
15
  - **Updates**
7
16
  - [CLIENT-2526] Support for set quota for user defined roles
@@ -110,14 +110,23 @@ module Aerospike
110
110
  self
111
111
  end
112
112
 
113
- ##
114
- # Creates a map create operation.
115
- # Server creates map at given context level.
116
- def self.create(bin_name, order, ctx: nil)
117
- if !ctx || ctx.length == 0
113
+ # Create map create operation.
114
+ # Server creates a map at the given context level.
115
+ #
116
+ # @param [String] bin_name The bin name.
117
+ # @param [Integer] order The map order.
118
+ # @param [Boolean] persist_index If true, persist map index. A map index improves lookup performance,
119
+ # but requires more storage. A map index can be created for a top-level
120
+ # ordered map only. Nested and unordered map indexes are not supported.
121
+ # @param [String] ctx Optional path to a nested map. If not defined, the top-level map is used.
122
+ def self.create(bin_name, order, persistent_index, ctx: nil)
123
+ if !ctx || ctx.empty?
118
124
  # If context not defined, the set order for top-level bin map.
119
- self.set_policy(MapPolicy.new(order: order, flag: 0), bin_name)
125
+ attr = order[:attr]
126
+ attr += 0x10 if persistent_index
127
+ MapOperation.new(Operation::CDT_MODIFY, SET_TYPE, bin_name, attr, ctx: ctx, flag: order[:flag])
120
128
  else
129
+ # Create nested map. persistIndex does not apply here, so ignore it
121
130
  MapOperation.new(Operation::CDT_MODIFY, SET_TYPE, bin_name, order[:attr], ctx: ctx, flag: order[:flag])
122
131
  end
123
132
  end
@@ -128,7 +137,12 @@ module Aerospike
128
137
  #
129
138
  # The required map policy attributes can be changed after the map is created.
130
139
  def self.set_policy(bin_name, policy, ctx: nil)
131
- MapOperation.new(Operation::CDT_MODIFY, SET_TYPE, bin_name, policy.order[:attr], ctx: ctx)
140
+ attr = policy.attributes
141
+ # Remove persistIndex flag for nested maps.
142
+ if !ctx.nil? && !ctx.empty? && (attr & 0x10) != 0
143
+ attr &= ~0x10
144
+ end
145
+ MapOperation.new(Operation::CDT_MODIFY, SET_TYPE, bin_name, attr, ctx: ctx)
132
146
  end
133
147
 
134
148
  ##
@@ -635,7 +649,7 @@ module Aerospike
635
649
  args.unshift(return_type) if return_type
636
650
 
637
651
  Packer.use do |packer|
638
- if @ctx != nil && @ctx.length > 0
652
+ if @ctx != nil && !@ctx.empty?
639
653
  packer.write_array_header(3)
640
654
  Value.of(0xff).pack(packer)
641
655
 
@@ -645,12 +659,12 @@ module Aerospike
645
659
  Value.of(@map_op).pack(packer)
646
660
  else
647
661
  packer.write_raw_short(@map_op)
648
- if args.length > 0
662
+ if !args.empty?
649
663
  packer.write_array_header(args.length)
650
664
  end
651
665
  end
652
666
 
653
- if args.length > 0
667
+ if !args.empty?
654
668
  args.each do |value|
655
669
  Value.of(value).pack(packer)
656
670
  end
@@ -17,10 +17,9 @@
17
17
  module Aerospike
18
18
  module CDT
19
19
  class MapPolicy
20
- attr_accessor :order, :write_mode, :flags
21
- attr_accessor :item_command, :items_command, :attributes
20
+ attr_accessor :order, :write_mode, :flags, :item_command, :items_command, :attributes, :persist_index
22
21
 
23
- def initialize(order: nil, write_mode: nil, flags: nil)
22
+ def initialize(order: nil, write_mode: nil, persist_index: false, flags: nil)
24
23
  if write_mode && flags
25
24
  raise ArgumentError, "Use write mode for server versions < 4.3; use write flags for server versions >= 4.3."
26
25
  end
@@ -30,6 +29,10 @@ module Aerospike
30
29
  @flags = flags || MapWriteFlags::DEFAULT
31
30
  @attributes = order ? order[:attr] : 0
32
31
 
32
+ if @persist_index
33
+ @attributes |= 0x10
34
+ end
35
+
33
36
  case @write_mode
34
37
  when CDT::MapWriteMode::DEFAULT
35
38
  @item_command = CDT::MapOperation::PUT
@@ -529,7 +529,7 @@ module Aerospike
529
529
  # This method is only supported by Aerospike 3 servers.
530
530
  # If the policy is nil, the default relevant policy will be used.
531
531
  def execute_udf_on_query(statement, package_name, function_name, function_args = [], options = nil)
532
- policy = create_policy(options, QueryPolicy, default_query_policy)
532
+ policy = create_policy(options, WritePolicy, default_write_policy)
533
533
 
534
534
  nodes = @cluster.nodes
535
535
  if nodes.empty?
@@ -538,14 +538,12 @@ module Aerospike
538
538
 
539
539
  statement = statement.clone
540
540
  statement.set_aggregate_function(package_name, function_name, function_args, false)
541
-
542
541
  # Use a thread per node
543
542
  nodes.each do |node|
544
- partitions = node.cluster.node_partitions(node, statement.namespace)
545
543
  Thread.new do
546
544
  Thread.current.abort_on_exception = true
547
545
  begin
548
- command = QueryCommand.new(node, policy, statement, nil, partitions)
546
+ command = ServerCommand.new(@cluster, node, policy, statement, true, statement.task_id)
549
547
  execute_command(command)
550
548
  rescue => e
551
549
  Aerospike.logger.error(e)
@@ -701,7 +699,6 @@ module Aerospike
701
699
  # If the policy is nil, the default relevant policy will be used.
702
700
  def query_partitions(partition_filter, statement, options = nil)
703
701
  policy = create_policy(options, QueryPolicy, default_query_policy)
704
- new_policy = policy.clone
705
702
 
706
703
  nodes = @cluster.nodes
707
704
  if nodes.empty?
@@ -60,7 +60,7 @@ module Aerospike
60
60
  operation_count = bin_names.length
61
61
  end
62
62
 
63
- write_header(policy, read_attr, 0, 2, operation_count)
63
+ write_header_read(policy, read_attr, 0, 2, operation_count)
64
64
  write_field_string(batch.namespace, Aerospike::FieldType::NAMESPACE)
65
65
  write_field_header(byte_size, Aerospike::FieldType::DIGEST_RIPE_ARRAY)
66
66
 
@@ -66,7 +66,7 @@ module Aerospike
66
66
  end
67
67
  end
68
68
  size_buffer
69
- write_header(policy,read_attr | INFO1_BATCH, 0, field_count, 0)
69
+ write_header_read(policy, read_attr | INFO1_BATCH, 0, field_count, 0)
70
70
 
71
71
  write_predexp(@policy.predexp, predexp_size)
72
72
 
@@ -124,7 +124,7 @@ module Aerospike
124
124
 
125
125
  size_buffer
126
126
 
127
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, bins.length)
127
+ write_header_write(policy, INFO2_WRITE, field_count, bins.length)
128
128
  write_key(key, policy)
129
129
  write_predexp(policy.predexp, predexp_size)
130
130
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -149,7 +149,7 @@ module Aerospike
149
149
  field_count += 1 if exp_size > 0
150
150
 
151
151
  size_buffer
152
- write_header_with_policy(policy, 0, INFO2_WRITE | INFO2_DELETE, field_count, 0)
152
+ write_header_write(policy, INFO2_WRITE | INFO2_DELETE, field_count, 0)
153
153
  write_key(key)
154
154
  write_predexp(policy.predexp, predexp_size)
155
155
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -169,7 +169,7 @@ module Aerospike
169
169
 
170
170
  estimate_operation_size
171
171
  size_buffer
172
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, 1)
172
+ write_header_write(policy, INFO2_WRITE, field_count, 1)
173
173
  write_key(key)
174
174
  write_predexp(policy.predexp, predexp_size)
175
175
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -189,7 +189,7 @@ module Aerospike
189
189
  field_count += 1 if exp_size > 0
190
190
 
191
191
  size_buffer
192
- write_header(policy, INFO1_READ | INFO1_NOBINDATA, 0, field_count, 0)
192
+ write_header_read_header(policy, INFO1_READ | INFO1_NOBINDATA, field_count, 0)
193
193
  write_key(key)
194
194
  write_predexp(policy.predexp, predexp_size)
195
195
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -208,7 +208,7 @@ module Aerospike
208
208
  field_count += 1 if exp_size > 0
209
209
 
210
210
  size_buffer
211
- write_header(policy, INFO1_READ | INFO1_GET_ALL, 0, field_count, 0)
211
+ write_header_read(policy, INFO1_READ | INFO1_GET_ALL, 0, field_count, 0)
212
212
  write_key(key)
213
213
  write_predexp(policy.predexp, predexp_size)
214
214
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -217,7 +217,7 @@ module Aerospike
217
217
 
218
218
  # Writes the command for get operations (specified bins)
219
219
  def set_read(policy, key, bin_names)
220
- if bin_names && bin_names.length > 0
220
+ if bin_names && !bin_names.empty?
221
221
  begin_cmd
222
222
  field_count = estimate_key_size(key)
223
223
 
@@ -232,7 +232,12 @@ module Aerospike
232
232
  end
233
233
 
234
234
  size_buffer
235
- write_header(policy, INFO1_READ, 0, field_count, bin_names.length)
235
+ attr = INFO1_READ
236
+ if bin_names.empty?
237
+ attr |= INFO1_GET_ALL
238
+ end
239
+
240
+ write_header_read(policy, attr, 0, field_count, bin_names.length)
236
241
  write_key(key)
237
242
  write_predexp(policy.predexp, predexp_size)
238
243
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -242,6 +247,7 @@ module Aerospike
242
247
  end
243
248
 
244
249
  end_cmd
250
+ mark_compressed(policy)
245
251
  else
246
252
  set_read_for_key_only(policy, key)
247
253
  end
@@ -258,20 +264,19 @@ module Aerospike
258
264
  exp_size = estimate_expression_size(@policy.filter_exp)
259
265
  field_count += 1 if exp_size > 0
260
266
 
261
- estimate_operation_size_for_bin_name("")
262
267
  size_buffer
263
268
 
264
269
  # The server does not currently return record header data with _INFO1_NOBINDATA attribute set.
265
270
  # The workaround is to request a non-existent bin.
266
271
  # TODO: Fix this on server.
267
272
  #command.set_read(INFO1_READ | _INFO1_NOBINDATA);
268
- write_header(policy, INFO1_READ, 0, field_count, 1)
273
+ write_header_read_header(policy, INFO1_READ|INFO1_NOBINDATA, field_count, 0)
269
274
 
270
275
  write_key(key)
271
276
  write_predexp(policy.predexp, predexp_size)
272
277
  write_filter_exp(@policy.filter_exp, exp_size)
273
- write_operation_for_bin_name("", Aerospike::Operation::READ)
274
278
  end_cmd
279
+ mark_compressed(policy)
275
280
  end
276
281
 
277
282
  # Implements different command operations
@@ -289,7 +294,7 @@ module Aerospike
289
294
 
290
295
  size_buffer
291
296
 
292
- write_header_with_policy(policy, args.read_attr, args.write_attr, field_count, args.operations.length)
297
+ write_header_read_write(policy, args.read_attr, args.write_attr, field_count, args.operations.length)
293
298
  write_key(key, policy)
294
299
  write_predexp(policy.predexp, predexp_size)
295
300
  write_filter_exp(policy.filter_exp, exp_size)
@@ -317,7 +322,7 @@ module Aerospike
317
322
  field_count += estimate_udf_size(package_name, function_name, arg_bytes)
318
323
  size_buffer
319
324
 
320
- write_header(policy, 0, INFO2_WRITE, field_count, 0)
325
+ write_header_write(policy, INFO2_WRITE, field_count, 0)
321
326
  write_key(key, policy)
322
327
  write_predexp(policy.predexp, predexp_size)
323
328
  write_filter_exp(@policy.filter_exp, exp_size)
@@ -329,7 +334,7 @@ module Aerospike
329
334
  mark_compressed(policy)
330
335
  end
331
336
 
332
- def set_scan(policy, namespace, set_name, bin_names, node_partitions)
337
+ def set_scan(cluster, policy, namespace, set_name, bin_names, node_partitions)
333
338
  # Estimate buffer size
334
339
  begin_cmd
335
340
  field_count = 0
@@ -395,12 +400,17 @@ module Aerospike
395
400
  read_attr |= INFO1_NOBINDATA
396
401
  end
397
402
 
403
+ info_attr = 0
404
+ if cluster.supports_feature?(Aerospike::Features::PARTITION_QUERY)
405
+ info_attr = INFO3_PARTITION_DONE
406
+ end
407
+
398
408
  operation_count = 0
399
- if bin_names
409
+ unless bin_names.nil?
400
410
  operation_count = bin_names.length
401
411
  end
402
412
 
403
- write_header(policy, read_attr, 0, field_count, operation_count)
413
+ write_header_read(policy, read_attr, info_attr, field_count, operation_count)
404
414
 
405
415
  if namespace
406
416
  write_field_string(namespace, Aerospike::FieldType::NAMESPACE)
@@ -465,11 +475,13 @@ module Aerospike
465
475
  end_cmd
466
476
  end
467
477
 
468
- def set_query(policy, statement, background, node_partitions)
478
+
479
+ def set_query(cluster, policy, statement, background, node_partitions)
469
480
  function_arg_buffer = nil
470
481
  field_count = 0
471
482
  filter_size = 0
472
483
 
484
+ is_new = cluster.supports_feature?(Aerospike::Features::PARTITION_QUERY)
473
485
  begin_cmd
474
486
 
475
487
  if statement.namespace
@@ -548,7 +560,7 @@ module Aerospike
548
560
  @data_offset += statement.function_name.bytesize + FIELD_HEADER_SIZE
549
561
 
550
562
  function_arg_buffer = ""
551
- if statement.function_args && statement.function_args.length > 0
563
+ if statement.function_args && !statement.function_args.empty?
552
564
  function_arg_buffer = Value.of(statement.function_args).to_bytes
553
565
  end
554
566
  @data_offset += FIELD_HEADER_SIZE + function_arg_buffer.bytesize
@@ -592,10 +604,13 @@ module Aerospike
592
604
  field_count += 1
593
605
  end
594
606
 
595
- operations = statement.operations
607
+ unless statement.operations.nil?
608
+ operations = statement.operations
609
+ end
610
+
596
611
  operation_count = 0
597
612
 
598
- if !operations.empty?
613
+ if operations
599
614
 
600
615
  unless background
601
616
  raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR)
@@ -616,17 +631,20 @@ module Aerospike
616
631
  size_buffer
617
632
 
618
633
  if background
619
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, operation_count)
634
+ write_header_write(policy, INFO2_WRITE, field_count, operation_count)
620
635
  else
621
636
  read_attr = INFO1_READ
622
637
  read_attr |= INFO1_NOBINDATA unless policy.include_bin_data
623
638
  read_attr |= INFO1_SHORT_QUERY if policy.short_query
624
- write_header(policy, read_attr, 0, field_count, operation_count)
639
+ info_attr = INFO3_PARTITION_DONE if is_new
640
+ write_header_read(policy, read_attr, info_attr, field_count, operation_count)
625
641
  end
626
642
 
643
+
627
644
  write_field_string(statement.namespace, FieldType::NAMESPACE) if statement.namespace
628
645
  write_field_string(statement.set_name, FieldType::TABLE) if statement.set_name
629
646
 
647
+
630
648
  # Write records per second.
631
649
  write_field_int(statement.records_per_second, FieldType::RECORDS_PER_SECOND) if statement.records_per_second > 0
632
650
 
@@ -670,7 +688,6 @@ module Aerospike
670
688
  write_field_string(statement.function_name, FieldType::UDF_FUNCTION)
671
689
  write_field_string(function_arg_buffer, FieldType::UDF_ARGLIST)
672
690
  end
673
-
674
691
  if parts_full_size > 0
675
692
  write_field_header(parts_full_size, FieldType::PID_ARRAY)
676
693
  node_partitions.parts_full.each do |part|
@@ -696,23 +713,19 @@ module Aerospike
696
713
  write_field(max_records, FieldType::MAX_RECORDS)
697
714
  end
698
715
 
699
- if operations.empty?
700
- if bin_names.empty?
701
- bin_names.each do |bin_name|
702
- write_operation_for_bin_name(bin_name, Operation::READ)
703
- end
704
- end
705
- else
716
+ if !operations.nil?
706
717
  operations.each do |operation|
707
718
  write_operation_for_operation(operation)
708
719
  end
720
+ elsif !bin_names.nil? && (is_new || filter.nil?)
721
+ bin_names.each do |bin_name|
722
+ write_operation_for_bin_name(bin_name, Operation::READ)
723
+ end
709
724
  end
710
-
711
725
  end_cmd
712
-
713
- nil
714
726
  end
715
727
 
728
+
716
729
  def execute
717
730
  iterations = 0
718
731
 
@@ -764,7 +777,6 @@ module Aerospike
764
777
 
765
778
  # Reset timeout in send buffer (destined for server) and socket.
766
779
  @data_buffer.write_int32((@policy.timeout * 1000).to_i, 22)
767
-
768
780
  # Send command.
769
781
  begin
770
782
  @conn.write(@data_buffer, @data_offset)
@@ -879,7 +891,7 @@ module Aerospike
879
891
  end
880
892
 
881
893
  def estimate_predexp(predexp)
882
- if predexp && predexp.size > 0
894
+ if predexp && !predexp.empty?
883
895
  @data_offset += FIELD_HEADER_SIZE
884
896
  sz = Aerospike::PredExp.estimate_size(predexp)
885
897
  @data_offset += sz
@@ -897,21 +909,52 @@ module Aerospike
897
909
  0
898
910
  end
899
911
 
900
- # Generic header write.
901
- def write_header(policy, read_attr, write_attr, field_count, operation_count)
902
- read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
903
- read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
912
+ # Header write for write command
913
+ def write_header_write(policy, write_attr, field_count, operation_count)
914
+ # Set flags.
915
+ generation = Integer(0)
916
+ info_attr = Integer(0)
917
+ read_attr = Integer(0)
918
+
919
+ case policy.record_exists_action
920
+ when Aerospike::RecordExistsAction::UPDATE
921
+ when Aerospike::RecordExistsAction::UPDATE_ONLY
922
+ info_attr |= INFO3_UPDATE_ONLY
923
+ when Aerospike::RecordExistsAction::REPLACE
924
+ info_attr |= INFO3_CREATE_OR_REPLACE
925
+ when Aerospike::RecordExistsAction::REPLACE_ONLY
926
+ info_attr |= INFO3_REPLACE_ONLY
927
+ when Aerospike::RecordExistsAction::CREATE_ONLY
928
+ write_attr |= INFO2_CREATE_ONLY
929
+ end
904
930
 
931
+ case policy.generation_policy
932
+ when Aerospike::GenerationPolicy::NONE
933
+ when Aerospike::GenerationPolicy::EXPECT_GEN_EQUAL
934
+ generation = policy.generation
935
+ write_attr |= INFO2_GENERATION
936
+ when Aerospike::GenerationPolicy::EXPECT_GEN_GT
937
+ generation = policy.generation
938
+ write_attr |= INFO2_GENERATION_GT
939
+ end
940
+
941
+ info_attr |= INFO3_COMMIT_MASTER if policy.commit_level == Aerospike::CommitLevel::COMMIT_MASTER
942
+ write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
905
943
  # Write all header data except total size which must be written last.
906
- @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message heade.length.
944
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
907
945
  @data_buffer.write_byte(read_attr, 9)
908
946
  @data_buffer.write_byte(write_attr, 10)
947
+ @data_buffer.write_byte(info_attr, 11)
948
+ @data_buffer.write_byte(0, 12) # unused
949
+ @data_buffer.write_byte(0, 13) # clear the result code
950
+ @data_buffer.write_uint32(generation, 14)
951
+ @data_buffer.write_uint32(policy.ttl, 18)
909
952
 
910
- i = 11
911
- while i <= 25
912
- @data_buffer.write_byte(0, i)
913
- i = i.succ
914
- end
953
+ # Initialize timeout. It will be written later.
954
+ @data_buffer.write_byte(0, 22)
955
+ @data_buffer.write_byte(0, 23)
956
+ @data_buffer.write_byte(0, 24)
957
+ @data_buffer.write_byte(0, 25)
915
958
 
916
959
  @data_buffer.write_int16(field_count, 26)
917
960
  @data_buffer.write_int16(operation_count, 28)
@@ -920,7 +963,7 @@ module Aerospike
920
963
  end
921
964
 
922
965
  # Header write for write operations.
923
- def write_header_with_policy(policy, read_attr, write_attr, field_count, operation_count)
966
+ def write_header_read_write(policy, read_attr, write_attr, field_count, operation_count)
924
967
  # Set flags.
925
968
  generation = Integer(0)
926
969
  info_attr = Integer(0)
@@ -948,9 +991,9 @@ module Aerospike
948
991
  end
949
992
 
950
993
  info_attr |= INFO3_COMMIT_MASTER if policy.commit_level == Aerospike::CommitLevel::COMMIT_MASTER
951
- read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
952
994
  write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
953
995
  read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
996
+
954
997
  # Write all header data except total size which must be written last.
955
998
  @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
956
999
  @data_buffer.write_byte(read_attr, 9)
@@ -973,6 +1016,52 @@ module Aerospike
973
1016
  @data_offset = MSG_TOTAL_HEADER_SIZE
974
1017
  end
975
1018
 
1019
+ def write_header_read(policy, read_attr, info_attr, field_count, operation_count)
1020
+ read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
1021
+ #TODO: Add SC Mode
1022
+
1023
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
1024
+ @data_buffer.write_byte(read_attr, 9)
1025
+ @data_buffer.write_byte(0, 10)
1026
+ @data_buffer.write_byte(info_attr, 11)
1027
+
1028
+ (12...22).each { |i| @data_buffer.write_byte(i, 0) }
1029
+
1030
+ # Initialize timeout. It will be written later.
1031
+ @data_buffer.write_byte(0, 22)
1032
+ @data_buffer.write_byte(0, 23)
1033
+ @data_buffer.write_byte(0, 24)
1034
+ @data_buffer.write_byte(0, 25)
1035
+
1036
+ @data_buffer.write_int16(field_count, 26)
1037
+ @data_buffer.write_int16(operation_count, 28)
1038
+
1039
+ @data_offset = MSG_TOTAL_HEADER_SIZE
1040
+ end
1041
+
1042
+ def write_header_read_header(policy, read_attr, field_count, operation_count)
1043
+ info_attr = Integer(0)
1044
+ #TODO: Add SC Mode
1045
+
1046
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
1047
+ @data_buffer.write_byte(read_attr, 9)
1048
+ @data_buffer.write_byte(0, 10)
1049
+ @data_buffer.write_byte(info_attr, 11)
1050
+
1051
+ (12...22).each { |i| @data_buffer.write_byte(i, 0) }
1052
+
1053
+ # Initialize timeout. It will be written later.
1054
+ @data_buffer.write_byte(0, 22)
1055
+ @data_buffer.write_byte(0, 23)
1056
+ @data_buffer.write_byte(0, 24)
1057
+ @data_buffer.write_byte(0, 25)
1058
+
1059
+ @data_buffer.write_int16(field_count, 26)
1060
+ @data_buffer.write_int16(operation_count, 28)
1061
+
1062
+ @data_offset = MSG_TOTAL_HEADER_SIZE
1063
+ end
1064
+
976
1065
  def write_key(key, policy = nil)
977
1066
  # Write key into buffer.
978
1067
  if key.namespace
@@ -1111,7 +1200,7 @@ module Aerospike
1111
1200
  end
1112
1201
 
1113
1202
  def write_predexp(predexp, predexp_size)
1114
- if predexp && predexp.size > 0
1203
+ if predexp && !predexp.empty?
1115
1204
  write_field_header(predexp_size, Aerospike::FieldType::FILTER_EXP)
1116
1205
  @data_offset = Aerospike::PredExp.write(
1117
1206
  predexp, @data_buffer, @data_offset
@@ -1152,13 +1241,13 @@ module Aerospike
1152
1241
  compressed = Zlib::deflate(@data_buffer.buf, Zlib::DEFAULT_COMPRESSION)
1153
1242
 
1154
1243
  # write original size as header
1155
- proto_s = "%08d" % 0
1244
+ proto_s = format("%08d", 0)
1156
1245
  proto_s[0, 8] = [@data_offset].pack("q>")
1157
1246
  compressed.prepend(proto_s)
1158
1247
 
1159
1248
  # write proto
1160
1249
  proto = (compressed.size + 8) | Integer(CL_MSG_VERSION << 56) | Integer(AS_MSG_TYPE << 48)
1161
- proto_s = "%08d" % 0
1250
+ proto_s = format("%08d", 0)
1162
1251
  proto_s[0, 8] = [proto].pack("q>")
1163
1252
  compressed.prepend(proto_s)
1164
1253
 
@@ -40,7 +40,7 @@ module Aerospike
40
40
  end
41
41
 
42
42
  def empty_socket
43
- # There should not be any more bytes.
43
+ # There should not be any more get_bytes.
44
44
  # Empty the socket to be safe.
45
45
  sz = @data_buffer.read_int64( 0)
46
46
  header_length = @data_buffer.read(8).ord
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2022 Aerospike, Inc.
2
+ # Copyright 2014-2023 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -210,7 +210,7 @@ module Aerospike
210
210
  # # Bin "a" exists in record
211
211
  # Exp.bin_exists("a")
212
212
  def self.bin_exists(name)
213
- return Exp.ne(Exp.bin_type(name), Exp.int_val(0))
213
+ Exp.ne(Exp.bin_type(name), Exp.int_val(0))
214
214
  end
215
215
 
216
216
  # Create expression that returns bin's integer particle type::
@@ -223,6 +223,20 @@ module Aerospike
223
223
  CmdStr.new(BIN_TYPE, name)
224
224
  end
225
225
 
226
+ # Create expression that returns the record size. This expression usually evaluates
227
+ # quickly because record meta data is cached in memory.
228
+ # Requires server version 7.0+. This expression replaces {@link #deviceSize()} and
229
+ # {@link #memorySize()} since those older expressions are equivalent on server version 7.0+.
230
+ #
231
+ # {@code
232
+ # // Record size >= 100 KB
233
+ # Exp.ge(Exp.record_size(), Exp.val(100 * 1024))
234
+ # }
235
+ def self.record_size
236
+ Cmd.new(RECORD_SIZE)
237
+ end
238
+
239
+
226
240
  #--------------------------------------------------
227
241
  # Misc
228
242
  #--------------------------------------------------
@@ -900,6 +914,19 @@ module Aerospike
900
914
  def self.var(name)
901
915
  CmdStr.new(VAR, name)
902
916
  end
917
+ #--------------------------------------------------
918
+ # Build
919
+ #--------------------------------------------------
920
+
921
+ #
922
+ # Create final expression that contains packed byte instructions used in the wire protocol.
923
+
924
+ def self.build(exp)
925
+ Packer.use do |packer|
926
+ exp.pack(packer)
927
+ @bytes = packer.bytes
928
+ end
929
+ end
903
930
 
904
931
  #--------------------------------------------------
905
932
  # Miscellaneous
@@ -922,6 +949,7 @@ module Aerospike
922
949
  Cmd.new(UNKNOWN)
923
950
  end
924
951
 
952
+
925
953
  # # Merge precompiled expression into a new expression tree.
926
954
  # # Useful for storing common precompiled expressions and then reusing
927
955
  # # these expressions as part of a greater expression.
@@ -1010,6 +1038,7 @@ module Aerospike
1010
1038
  KEY_EXISTS = 71
1011
1039
  IS_TOMBSTONE = 72
1012
1040
  MEMORY_SIZE = 73
1041
+ RECORD_SIZE = 74
1013
1042
  KEY = 80
1014
1043
  BIN = 81
1015
1044
  BIN_TYPE = 82