aerospike 2.29.0 → 3.0.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: 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