aerospike 2.29.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +13 -9
  4. data/lib/aerospike/batch_attr.rb +292 -0
  5. data/lib/aerospike/batch_delete.rb +48 -0
  6. data/lib/aerospike/batch_read.rb +97 -0
  7. data/lib/aerospike/batch_record.rb +83 -0
  8. data/lib/aerospike/batch_results.rb +38 -0
  9. data/lib/aerospike/batch_udf.rb +76 -0
  10. data/lib/aerospike/batch_write.rb +79 -0
  11. data/lib/aerospike/cdt/bit_operation.rb +4 -5
  12. data/lib/aerospike/cdt/map_operation.rb +24 -10
  13. data/lib/aerospike/cdt/map_policy.rb +6 -3
  14. data/lib/aerospike/cdt/map_return_type.rb +8 -0
  15. data/lib/aerospike/client.rb +39 -56
  16. data/lib/aerospike/cluster.rb +50 -46
  17. data/lib/aerospike/command/batch_index_command.rb +7 -11
  18. data/lib/aerospike/command/batch_index_node.rb +3 -4
  19. data/lib/aerospike/command/batch_operate_command.rb +151 -0
  20. data/lib/aerospike/command/batch_operate_node.rb +51 -0
  21. data/lib/aerospike/command/command.rb +231 -128
  22. data/lib/aerospike/exp/exp.rb +54 -27
  23. data/lib/aerospike/exp/exp_bit.rb +24 -24
  24. data/lib/aerospike/exp/exp_hll.rb +12 -12
  25. data/lib/aerospike/exp/exp_list.rb +101 -86
  26. data/lib/aerospike/exp/exp_map.rb +118 -110
  27. data/lib/aerospike/exp/operation.rb +2 -2
  28. data/lib/aerospike/info.rb +2 -4
  29. data/lib/aerospike/node.rb +20 -3
  30. data/lib/aerospike/operation.rb +38 -0
  31. data/lib/aerospike/policy/batch_delete_policy.rb +71 -0
  32. data/lib/aerospike/policy/batch_policy.rb +53 -4
  33. data/lib/aerospike/{command/batch_direct_node.rb → policy/batch_read_policy.rb} +17 -19
  34. data/lib/aerospike/policy/batch_udf_policy.rb +75 -0
  35. data/lib/aerospike/policy/batch_write_policy.rb +105 -0
  36. data/lib/aerospike/policy/policy.rb +3 -40
  37. data/lib/aerospike/query/query_command.rb +3 -205
  38. data/lib/aerospike/query/query_executor.rb +2 -2
  39. data/lib/aerospike/query/query_partition_command.rb +4 -230
  40. data/lib/aerospike/query/scan_executor.rb +2 -2
  41. data/lib/aerospike/query/scan_partition_command.rb +3 -3
  42. data/lib/aerospike/query/server_command.rb +2 -2
  43. data/lib/aerospike/query/statement.rb +5 -21
  44. data/lib/aerospike/task/execute_task.rb +2 -2
  45. data/lib/aerospike/utils/buffer.rb +15 -15
  46. data/lib/aerospike/version.rb +1 -1
  47. data/lib/aerospike.rb +13 -12
  48. metadata +16 -14
  49. data/lib/aerospike/command/batch_direct_command.rb +0 -105
  50. data/lib/aerospike/command/batch_direct_exists_command.rb +0 -51
  51. data/lib/aerospike/query/pred_exp/and_or.rb +0 -32
  52. data/lib/aerospike/query/pred_exp/geo_json_value.rb +0 -41
  53. data/lib/aerospike/query/pred_exp/integer_value.rb +0 -32
  54. data/lib/aerospike/query/pred_exp/op.rb +0 -27
  55. data/lib/aerospike/query/pred_exp/regex.rb +0 -32
  56. data/lib/aerospike/query/pred_exp/regex_flags.rb +0 -23
  57. data/lib/aerospike/query/pred_exp/string_value.rb +0 -29
  58. data/lib/aerospike/query/pred_exp.rb +0 -192
@@ -76,6 +76,12 @@ module Aerospike
76
76
  # Completely replace existing record only.
77
77
  INFO3_REPLACE_ONLY = Integer(1 << 5)
78
78
 
79
+ BATCH_MSG_READ = 0x0
80
+ BATCH_MSG_REPEAT = 0x1
81
+ BATCH_MSG_INFO = 0x2
82
+ BATCH_MSG_GEN = 0x4
83
+ BATCH_MSG_TTL = 0x8
84
+
79
85
  MSG_TOTAL_HEADER_SIZE = 30
80
86
  FIELD_HEADER_SIZE = 5
81
87
  OPERATION_HEADER_SIZE = 8
@@ -112,9 +118,6 @@ module Aerospike
112
118
  begin_cmd
113
119
  field_count = estimate_key_size(key, policy)
114
120
 
115
- predexp_size = estimate_predexp(policy.predexp)
116
- field_count += 1 if predexp_size > 0
117
-
118
121
  exp_size = estimate_expression_size(@policy.filter_exp)
119
122
  field_count += 1 if exp_size > 0
120
123
 
@@ -124,9 +127,8 @@ module Aerospike
124
127
 
125
128
  size_buffer
126
129
 
127
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, bins.length)
130
+ write_header_write(policy, INFO2_WRITE, field_count, bins.length)
128
131
  write_key(key, policy)
129
- write_predexp(policy.predexp, predexp_size)
130
132
  write_filter_exp(@policy.filter_exp, exp_size)
131
133
 
132
134
  bins.each do |bin|
@@ -142,16 +144,12 @@ module Aerospike
142
144
  begin_cmd
143
145
  field_count = estimate_key_size(key)
144
146
 
145
- predexp_size = estimate_predexp(policy.predexp)
146
- field_count += 1 if predexp_size > 0
147
-
148
147
  exp_size = estimate_expression_size(@policy.filter_exp)
149
148
  field_count += 1 if exp_size > 0
150
149
 
151
150
  size_buffer
152
- write_header_with_policy(policy, 0, INFO2_WRITE | INFO2_DELETE, field_count, 0)
151
+ write_header_write(policy, INFO2_WRITE | INFO2_DELETE, field_count, 0)
153
152
  write_key(key)
154
- write_predexp(policy.predexp, predexp_size)
155
153
  write_filter_exp(@policy.filter_exp, exp_size)
156
154
  end_cmd
157
155
  end
@@ -161,17 +159,13 @@ module Aerospike
161
159
  begin_cmd
162
160
  field_count = estimate_key_size(key)
163
161
 
164
- predexp_size = estimate_predexp(policy.predexp)
165
- field_count += 1 if predexp_size > 0
166
-
167
162
  exp_size = estimate_expression_size(@policy.filter_exp)
168
163
  field_count += 1 if exp_size > 0
169
164
 
170
165
  estimate_operation_size
171
166
  size_buffer
172
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, 1)
167
+ write_header_write(policy, INFO2_WRITE, field_count, 1)
173
168
  write_key(key)
174
- write_predexp(policy.predexp, predexp_size)
175
169
  write_filter_exp(@policy.filter_exp, exp_size)
176
170
  write_operation_for_operation_type(Aerospike::Operation::TOUCH)
177
171
  end_cmd
@@ -182,16 +176,12 @@ module Aerospike
182
176
  begin_cmd
183
177
  field_count = estimate_key_size(key)
184
178
 
185
- predexp_size = estimate_predexp(policy.predexp)
186
- field_count += 1 if predexp_size > 0
187
-
188
179
  exp_size = estimate_expression_size(@policy.filter_exp)
189
180
  field_count += 1 if exp_size > 0
190
181
 
191
182
  size_buffer
192
- write_header(policy, INFO1_READ | INFO1_NOBINDATA, 0, field_count, 0)
183
+ write_header_read_header(policy, INFO1_READ | INFO1_NOBINDATA, field_count, 0)
193
184
  write_key(key)
194
- write_predexp(policy.predexp, predexp_size)
195
185
  write_filter_exp(@policy.filter_exp, exp_size)
196
186
  end_cmd
197
187
  end
@@ -201,29 +191,22 @@ module Aerospike
201
191
  begin_cmd
202
192
  field_count = estimate_key_size(key)
203
193
 
204
- predexp_size = estimate_predexp(policy.predexp)
205
- field_count += 1 if predexp_size > 0
206
-
207
194
  exp_size = estimate_expression_size(@policy.filter_exp)
208
195
  field_count += 1 if exp_size > 0
209
196
 
210
197
  size_buffer
211
- write_header(policy, INFO1_READ | INFO1_GET_ALL, 0, field_count, 0)
198
+ write_header_read(policy, INFO1_READ | INFO1_GET_ALL, 0, field_count, 0)
212
199
  write_key(key)
213
- write_predexp(policy.predexp, predexp_size)
214
200
  write_filter_exp(@policy.filter_exp, exp_size)
215
201
  end_cmd
216
202
  end
217
203
 
218
204
  # Writes the command for get operations (specified bins)
219
205
  def set_read(policy, key, bin_names)
220
- if bin_names && bin_names.length > 0
206
+ if bin_names && !bin_names.empty?
221
207
  begin_cmd
222
208
  field_count = estimate_key_size(key)
223
209
 
224
- predexp_size = estimate_predexp(policy.predexp)
225
- field_count += 1 if predexp_size > 0
226
-
227
210
  exp_size = estimate_expression_size(@policy.filter_exp)
228
211
  field_count += 1 if exp_size > 0
229
212
 
@@ -232,9 +215,13 @@ module Aerospike
232
215
  end
233
216
 
234
217
  size_buffer
235
- write_header(policy, INFO1_READ, 0, field_count, bin_names.length)
218
+ attr = INFO1_READ
219
+ if bin_names.empty?
220
+ attr |= INFO1_GET_ALL
221
+ end
222
+
223
+ write_header_read(policy, attr, 0, field_count, bin_names.length)
236
224
  write_key(key)
237
- write_predexp(policy.predexp, predexp_size)
238
225
  write_filter_exp(@policy.filter_exp, exp_size)
239
226
 
240
227
  bin_names.each do |bin_name|
@@ -242,6 +229,7 @@ module Aerospike
242
229
  end
243
230
 
244
231
  end_cmd
232
+ mark_compressed(policy)
245
233
  else
246
234
  set_read_for_key_only(policy, key)
247
235
  end
@@ -252,26 +240,21 @@ module Aerospike
252
240
  begin_cmd
253
241
  field_count = estimate_key_size(key)
254
242
 
255
- predexp_size = estimate_predexp(policy.predexp)
256
- field_count += 1 if predexp_size > 0
257
-
258
243
  exp_size = estimate_expression_size(@policy.filter_exp)
259
244
  field_count += 1 if exp_size > 0
260
245
 
261
- estimate_operation_size_for_bin_name("")
262
246
  size_buffer
263
247
 
264
248
  # The server does not currently return record header data with _INFO1_NOBINDATA attribute set.
265
249
  # The workaround is to request a non-existent bin.
266
250
  # TODO: Fix this on server.
267
251
  #command.set_read(INFO1_READ | _INFO1_NOBINDATA);
268
- write_header(policy, INFO1_READ, 0, field_count, 1)
252
+ write_header_read_header(policy, INFO1_READ|INFO1_NOBINDATA, field_count, 0)
269
253
 
270
254
  write_key(key)
271
- write_predexp(policy.predexp, predexp_size)
272
255
  write_filter_exp(@policy.filter_exp, exp_size)
273
- write_operation_for_bin_name("", Aerospike::Operation::READ)
274
256
  end_cmd
257
+ mark_compressed(policy)
275
258
  end
276
259
 
277
260
  # Implements different command operations
@@ -279,9 +262,6 @@ module Aerospike
279
262
  begin_cmd
280
263
  field_count = estimate_key_size(key, policy)
281
264
 
282
- predexp_size = estimate_predexp(policy.predexp)
283
- field_count += 1 if predexp_size > 0
284
-
285
265
  exp_size = estimate_expression_size(policy.filter_exp)
286
266
  field_count += 1 if exp_size > 0
287
267
 
@@ -289,9 +269,8 @@ module Aerospike
289
269
 
290
270
  size_buffer
291
271
 
292
- write_header_with_policy(policy, args.read_attr, args.write_attr, field_count, args.operations.length)
272
+ write_header_read_write(policy, args.read_attr, args.write_attr, field_count, args.operations.length)
293
273
  write_key(key, policy)
294
- write_predexp(policy.predexp, predexp_size)
295
274
  write_filter_exp(policy.filter_exp, exp_size)
296
275
 
297
276
  args.operations.each do |operation|
@@ -306,9 +285,6 @@ module Aerospike
306
285
  begin_cmd
307
286
  field_count = estimate_key_size(key, policy)
308
287
 
309
- predexp_size = estimate_predexp(policy.predexp)
310
- field_count += 1 if predexp_size > 0
311
-
312
288
  exp_size = estimate_expression_size(@policy.filter_exp)
313
289
  field_count += 1 if exp_size > 0
314
290
 
@@ -317,9 +293,8 @@ module Aerospike
317
293
  field_count += estimate_udf_size(package_name, function_name, arg_bytes)
318
294
  size_buffer
319
295
 
320
- write_header(policy, 0, INFO2_WRITE, field_count, 0)
296
+ write_header_write(policy, INFO2_WRITE, field_count, 0)
321
297
  write_key(key, policy)
322
- write_predexp(policy.predexp, predexp_size)
323
298
  write_filter_exp(@policy.filter_exp, exp_size)
324
299
  write_field_string(package_name, Aerospike::FieldType::UDF_PACKAGE_NAME)
325
300
  write_field_string(function_name, Aerospike::FieldType::UDF_FUNCTION)
@@ -329,7 +304,7 @@ module Aerospike
329
304
  mark_compressed(policy)
330
305
  end
331
306
 
332
- def set_scan(policy, namespace, set_name, bin_names, node_partitions)
307
+ def set_scan(cluster, policy, namespace, set_name, bin_names, node_partitions)
333
308
  # Estimate buffer size
334
309
  begin_cmd
335
310
  field_count = 0
@@ -368,9 +343,6 @@ module Aerospike
368
343
  field_count += 1
369
344
  end
370
345
 
371
- predexp_size = estimate_predexp(policy.predexp)
372
- field_count += 1 if predexp_size > 0
373
-
374
346
  exp_size = estimate_expression_size(@policy.filter_exp)
375
347
  field_count += 1 if exp_size > 0
376
348
 
@@ -395,12 +367,17 @@ module Aerospike
395
367
  read_attr |= INFO1_NOBINDATA
396
368
  end
397
369
 
370
+ info_attr = 0
371
+ if cluster.supports_feature?(Aerospike::Features::PARTITION_QUERY)
372
+ info_attr = INFO3_PARTITION_DONE
373
+ end
374
+
398
375
  operation_count = 0
399
- if bin_names
376
+ unless bin_names.nil?
400
377
  operation_count = bin_names.length
401
378
  end
402
379
 
403
- write_header(policy, read_attr, 0, field_count, operation_count)
380
+ write_header_read(policy, read_attr, info_attr, field_count, operation_count)
404
381
 
405
382
  if namespace
406
383
  write_field_string(namespace, Aerospike::FieldType::NAMESPACE)
@@ -436,7 +413,6 @@ module Aerospike
436
413
  write_field_int(policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
437
414
  end
438
415
 
439
- write_predexp(policy.predexp, predexp_size)
440
416
  write_filter_exp(@policy.filter_exp, exp_size)
441
417
 
442
418
  # write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
@@ -465,11 +441,12 @@ module Aerospike
465
441
  end_cmd
466
442
  end
467
443
 
468
- def set_query(policy, statement, background, node_partitions)
444
+ def set_query(cluster, policy, statement, background, node_partitions)
469
445
  function_arg_buffer = nil
470
446
  field_count = 0
471
447
  filter_size = 0
472
448
 
449
+ is_new = cluster.supports_feature?(Aerospike::Features::PARTITION_QUERY)
473
450
  begin_cmd
474
451
 
475
452
  if statement.namespace
@@ -513,7 +490,7 @@ module Aerospike
513
490
 
514
491
  # Estimate INDEX_RANGE field.
515
492
  @data_offset += FIELD_HEADER_SIZE
516
- filter_size += 1 # num filters
493
+ filter_size += 1 # num filters
517
494
  filter_size += filter.estimate_size
518
495
 
519
496
  @data_offset += filter_size
@@ -527,14 +504,6 @@ module Aerospike
527
504
  end
528
505
 
529
506
  statement.set_task_id
530
- predexp = policy.predexp || statement.predexp
531
-
532
- if predexp
533
- @data_offset += FIELD_HEADER_SIZE
534
- pred_size = Aerospike::PredExp.estimate_size(predexp)
535
- @data_offset += pred_size
536
- field_count += 1
537
- end
538
507
 
539
508
  unless policy.filter_exp.nil?
540
509
  exp_size = estimate_expression_size(policy.filter_exp)
@@ -548,7 +517,7 @@ module Aerospike
548
517
  @data_offset += statement.function_name.bytesize + FIELD_HEADER_SIZE
549
518
 
550
519
  function_arg_buffer = ""
551
- if statement.function_args && statement.function_args.length > 0
520
+ if statement.function_args && !statement.function_args.empty?
552
521
  function_arg_buffer = Value.of(statement.function_args).to_bytes
553
522
  end
554
523
  @data_offset += FIELD_HEADER_SIZE + function_arg_buffer.bytesize
@@ -592,10 +561,13 @@ module Aerospike
592
561
  field_count += 1
593
562
  end
594
563
 
595
- operations = statement.operations
564
+ unless statement.operations.nil?
565
+ operations = statement.operations
566
+ end
567
+
596
568
  operation_count = 0
597
569
 
598
- if !operations.empty?
570
+ if operations
599
571
 
600
572
  unless background
601
573
  raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR)
@@ -616,17 +588,20 @@ module Aerospike
616
588
  size_buffer
617
589
 
618
590
  if background
619
- write_header_with_policy(policy, 0, INFO2_WRITE, field_count, operation_count)
591
+ write_header_write(policy, INFO2_WRITE, field_count, operation_count)
620
592
  else
621
593
  read_attr = INFO1_READ
622
594
  read_attr |= INFO1_NOBINDATA unless policy.include_bin_data
623
595
  read_attr |= INFO1_SHORT_QUERY if policy.short_query
624
- write_header(policy, read_attr, 0, field_count, operation_count)
596
+ info_attr = INFO3_PARTITION_DONE if is_new
597
+ write_header_read(policy, read_attr, info_attr, field_count, operation_count)
625
598
  end
626
599
 
600
+
627
601
  write_field_string(statement.namespace, FieldType::NAMESPACE) if statement.namespace
628
602
  write_field_string(statement.set_name, FieldType::TABLE) if statement.set_name
629
603
 
604
+
630
605
  # Write records per second.
631
606
  write_field_int(statement.records_per_second, FieldType::RECORDS_PER_SECOND) if statement.records_per_second > 0
632
607
 
@@ -638,13 +613,6 @@ module Aerospike
638
613
  # Write task_id field
639
614
  write_field_int64(statement.task_id, FieldType::TRAN_ID)
640
615
 
641
- unless predexp.nil?
642
- write_field_header(pred_size, Aerospike::FieldType::PREDEXP)
643
- @data_offset = Aerospike::PredExp.write(
644
- predexp, @data_buffer, @data_offset
645
- )
646
- end
647
-
648
616
  if filter
649
617
  type = filter.collection_type
650
618
 
@@ -665,12 +633,12 @@ module Aerospike
665
633
 
666
634
  if statement.function_name
667
635
  write_field_header(1, FieldType::UDF_OP)
668
- @data_offset += @data_buffer.write_byte(1, @data_offset)
636
+ ret_marker = statement.return_data ? 1 : 2
637
+ @data_offset += @data_buffer.write_byte(ret_marker, @data_offset)
669
638
  write_field_string(statement.package_name, FieldType::UDF_PACKAGE_NAME)
670
639
  write_field_string(statement.function_name, FieldType::UDF_FUNCTION)
671
640
  write_field_string(function_arg_buffer, FieldType::UDF_ARGLIST)
672
641
  end
673
-
674
642
  if parts_full_size > 0
675
643
  write_field_header(parts_full_size, FieldType::PID_ARRAY)
676
644
  node_partitions.parts_full.each do |part|
@@ -696,21 +664,16 @@ module Aerospike
696
664
  write_field(max_records, FieldType::MAX_RECORDS)
697
665
  end
698
666
 
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
667
+ if !operations.nil?
706
668
  operations.each do |operation|
707
669
  write_operation_for_operation(operation)
708
670
  end
671
+ elsif !bin_names.nil? && (is_new || filter.nil?)
672
+ bin_names.each do |bin_name|
673
+ write_operation_for_bin_name(bin_name, Operation::READ)
674
+ end
709
675
  end
710
-
711
676
  end_cmd
712
-
713
- nil
714
677
  end
715
678
 
716
679
  def execute
@@ -739,7 +702,7 @@ module Aerospike
739
702
  # Socket connection error has occurred. Decrease health and retry.
740
703
  @node.decrease_health
741
704
 
742
- Aerospike.logger.error("Node #{@node.to_s}: #{e}")
705
+ Aerospike.logger.error("Node #{@node}: #{e}")
743
706
  else
744
707
  Aerospike.logger.error("No node available for transaction: #{e}")
745
708
  end
@@ -764,7 +727,6 @@ module Aerospike
764
727
 
765
728
  # Reset timeout in send buffer (destined for server) and socket.
766
729
  @data_buffer.write_int32((@policy.timeout * 1000).to_i, 22)
767
-
768
730
  # Send command.
769
731
  begin
770
732
  @conn.write(@data_buffer, @data_offset)
@@ -773,7 +735,7 @@ module Aerospike
773
735
  # Close socket to flush out possible garbage. Do not put back in pool.
774
736
  @conn.close if @conn
775
737
 
776
- Aerospike.logger.error("Node #{@node.to_s}: #{e}")
738
+ Aerospike.logger.error("Node #{@node}: #{e}")
777
739
  # IO error means connection to server @node is unhealthy.
778
740
  # Reflect cmd status.
779
741
  @node.decrease_health
@@ -841,14 +803,14 @@ module Aerospike
841
803
  field_count += 1
842
804
  end
843
805
 
844
- return field_count
806
+ field_count
845
807
  end
846
808
 
847
809
  def estimate_udf_size(package_name, function_name, bytes)
848
810
  @data_offset += package_name.bytesize + FIELD_HEADER_SIZE
849
811
  @data_offset += function_name.bytesize + FIELD_HEADER_SIZE
850
812
  @data_offset += bytes.bytesize + FIELD_HEADER_SIZE
851
- return 3
813
+ 3
852
814
  end
853
815
 
854
816
  def estimate_operation_size_for_bin(bin)
@@ -878,16 +840,6 @@ module Aerospike
878
840
  @data_offset += OPERATION_HEADER_SIZE
879
841
  end
880
842
 
881
- def estimate_predexp(predexp)
882
- if predexp && predexp.size > 0
883
- @data_offset += FIELD_HEADER_SIZE
884
- sz = Aerospike::PredExp.estimate_size(predexp)
885
- @data_offset += sz
886
- return sz
887
- end
888
- return 0
889
- end
890
-
891
843
  def estimate_expression_size(exp)
892
844
  unless exp.nil?
893
845
  @data_offset += FIELD_HEADER_SIZE
@@ -897,21 +849,52 @@ module Aerospike
897
849
  0
898
850
  end
899
851
 
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
852
+ # Header write for write command
853
+ def write_header_write(policy, write_attr, field_count, operation_count)
854
+ # Set flags.
855
+ generation = Integer(0)
856
+ info_attr = Integer(0)
857
+ read_attr = Integer(0)
858
+
859
+ case policy.record_exists_action
860
+ when Aerospike::RecordExistsAction::UPDATE
861
+ when Aerospike::RecordExistsAction::UPDATE_ONLY
862
+ info_attr |= INFO3_UPDATE_ONLY
863
+ when Aerospike::RecordExistsAction::REPLACE
864
+ info_attr |= INFO3_CREATE_OR_REPLACE
865
+ when Aerospike::RecordExistsAction::REPLACE_ONLY
866
+ info_attr |= INFO3_REPLACE_ONLY
867
+ when Aerospike::RecordExistsAction::CREATE_ONLY
868
+ write_attr |= INFO2_CREATE_ONLY
869
+ end
904
870
 
871
+ case policy.generation_policy
872
+ when Aerospike::GenerationPolicy::NONE
873
+ when Aerospike::GenerationPolicy::EXPECT_GEN_EQUAL
874
+ generation = policy.generation
875
+ write_attr |= INFO2_GENERATION
876
+ when Aerospike::GenerationPolicy::EXPECT_GEN_GT
877
+ generation = policy.generation
878
+ write_attr |= INFO2_GENERATION_GT
879
+ end
880
+
881
+ info_attr |= INFO3_COMMIT_MASTER if policy.commit_level == Aerospike::CommitLevel::COMMIT_MASTER
882
+ write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
905
883
  # 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.
884
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
907
885
  @data_buffer.write_byte(read_attr, 9)
908
886
  @data_buffer.write_byte(write_attr, 10)
887
+ @data_buffer.write_byte(info_attr, 11)
888
+ @data_buffer.write_byte(0, 12) # unused
889
+ @data_buffer.write_byte(0, 13) # clear the result code
890
+ @data_buffer.write_uint32(generation, 14)
891
+ @data_buffer.write_uint32(policy.ttl, 18)
909
892
 
910
- i = 11
911
- while i <= 25
912
- @data_buffer.write_byte(0, i)
913
- i = i.succ
914
- end
893
+ # Initialize timeout. It will be written later.
894
+ @data_buffer.write_byte(0, 22)
895
+ @data_buffer.write_byte(0, 23)
896
+ @data_buffer.write_byte(0, 24)
897
+ @data_buffer.write_byte(0, 25)
915
898
 
916
899
  @data_buffer.write_int16(field_count, 26)
917
900
  @data_buffer.write_int16(operation_count, 28)
@@ -920,7 +903,7 @@ module Aerospike
920
903
  end
921
904
 
922
905
  # Header write for write operations.
923
- def write_header_with_policy(policy, read_attr, write_attr, field_count, operation_count)
906
+ def write_header_read_write(policy, read_attr, write_attr, field_count, operation_count)
924
907
  # Set flags.
925
908
  generation = Integer(0)
926
909
  info_attr = Integer(0)
@@ -948,9 +931,9 @@ module Aerospike
948
931
  end
949
932
 
950
933
  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
934
  write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
953
935
  read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
936
+
954
937
  # Write all header data except total size which must be written last.
955
938
  @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
956
939
  @data_buffer.write_byte(read_attr, 9)
@@ -973,6 +956,135 @@ module Aerospike
973
956
  @data_offset = MSG_TOTAL_HEADER_SIZE
974
957
  end
975
958
 
959
+ def write_header_read(policy, read_attr, info_attr, field_count, operation_count)
960
+ read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
961
+ #TODO: Add SC Mode
962
+
963
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
964
+ @data_buffer.write_byte(read_attr, 9)
965
+ @data_buffer.write_byte(0, 10)
966
+ @data_buffer.write_byte(info_attr, 11)
967
+
968
+ (12...22).each { |i| @data_buffer.write_byte(0, i) }
969
+
970
+ # Initialize timeout. It will be written later.
971
+ @data_buffer.write_byte(0, 22)
972
+ @data_buffer.write_byte(0, 23)
973
+ @data_buffer.write_byte(0, 24)
974
+ @data_buffer.write_byte(0, 25)
975
+
976
+ @data_buffer.write_int16(field_count, 26)
977
+ @data_buffer.write_int16(operation_count, 28)
978
+
979
+ @data_offset = MSG_TOTAL_HEADER_SIZE
980
+ end
981
+
982
+ def write_header_read_header(policy, read_attr, field_count, operation_count)
983
+ info_attr = Integer(0)
984
+ #TODO: Add SC Mode
985
+
986
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
987
+ @data_buffer.write_byte(read_attr, 9)
988
+ @data_buffer.write_byte(0, 10)
989
+ @data_buffer.write_byte(info_attr, 11)
990
+
991
+ (12...22).each { |i| @data_buffer.write_byte(0, i) }
992
+
993
+ # Initialize timeout. It will be written later.
994
+ @data_buffer.write_byte(0, 22)
995
+ @data_buffer.write_byte(0, 23)
996
+ @data_buffer.write_byte(0, 24)
997
+ @data_buffer.write_byte(0, 25)
998
+
999
+ @data_buffer.write_int16(field_count, 26)
1000
+ @data_buffer.write_int16(operation_count, 28)
1001
+
1002
+ @data_offset = MSG_TOTAL_HEADER_SIZE
1003
+ end
1004
+
1005
+ def write_batch_operations(key, ops, attr, filter_exp)
1006
+ if attr.has_write
1007
+ write_batch_write(key, attr, filter_exp, 0, ops.length)
1008
+ else
1009
+ write_batch_read(key, attr, filter_exp, ops.length)
1010
+ end
1011
+
1012
+ ops.each do |op|
1013
+ write_operation_for_operation(op)
1014
+ end
1015
+ end
1016
+
1017
+ def write_batch_fields(key, field_count, op_count)
1018
+ field_count+=2
1019
+ @data_offset += @data_buffer.write_uint16(field_count, @data_offset)
1020
+ @data_offset += @data_buffer.write_uint16(op_count, @data_offset)
1021
+ write_field_string(key.namespace, Aerospike::FieldType::NAMESPACE)
1022
+ write_field_string(key.set_name, Aerospike::FieldType::TABLE)
1023
+ end
1024
+
1025
+ def write_batch_fields_with_filter(key, filter_exp, field_count, op_count)
1026
+ if filter_exp
1027
+ field_count+=1
1028
+ write_batch_fields(key, field_count, op_count)
1029
+ write_filter_exp(filter_exp, filter_exp.size)
1030
+ else
1031
+ write_batch_fields(key, field_count, op_count)
1032
+ end
1033
+ end
1034
+
1035
+ def write_batch_read(key, attr, filter_exp, op_count)
1036
+ @data_offset += @data_buffer.write_byte(BATCH_MSG_INFO | BATCH_MSG_TTL, @data_offset)
1037
+ @data_offset += @data_buffer.write_byte(attr.read_attr, @data_offset)
1038
+ @data_offset += @data_buffer.write_byte(attr.write_attr, @data_offset)
1039
+ @data_offset += @data_buffer.write_byte(attr.info_attr, @data_offset)
1040
+ @data_offset += @data_buffer.write_uint32(attr.expiration, @data_offset)
1041
+ write_batch_fields_with_filter(key, filter_exp, 0, op_count)
1042
+ end
1043
+
1044
+ def write_batch_write(key, attr, filter_exp, field_count, op_count)
1045
+ @data_offset += @data_buffer.write_byte(BATCH_MSG_INFO | BATCH_MSG_GEN | BATCH_MSG_TTL, @data_offset)
1046
+ @data_offset += @data_buffer.write_byte(attr.read_attr, @data_offset)
1047
+ @data_offset += @data_buffer.write_byte(attr.write_attr, @data_offset)
1048
+ @data_offset += @data_buffer.write_byte(attr.info_attr, @data_offset)
1049
+ @data_offset += @data_buffer.write_uint16(attr.generation, @data_offset)
1050
+ @data_offset += @data_buffer.write_uint32(attr.expiration, @data_offset)
1051
+ if attr.send_key
1052
+ field_count+=1
1053
+ write_batch_fields_with_filter(key, filter_exp, field_count, op_count)
1054
+ write_field_value(key.user_key, KEY)
1055
+ else
1056
+ write_batch_fields_with_filter(key, filter_exp, field_count, op_count)
1057
+ end
1058
+ end
1059
+
1060
+ def write_batch_bin_names(key, bin_names, attr, filter_exp)
1061
+ write_batch_read(key, attr, filter_exp, bin_names.length)
1062
+ bin_names.each do |bin_name|
1063
+ write_operation_for_bin_name(bin_name, Aerospike::Operation::READ)
1064
+ end
1065
+ end
1066
+
1067
+ def write_batch_header(policy, field_count)
1068
+ read_attr = INFO1_BATCH
1069
+ read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
1070
+ #TODO: Add SC Mode
1071
+
1072
+ @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length, @data_offset.
1073
+ @data_buffer.write_byte(read_attr, 9)
1074
+ @data_buffer.write_byte(0, 10)
1075
+ @data_buffer.write_byte(0, 11)
1076
+
1077
+ (12...22).each { |i| @data_buffer.write_byte(0, i) }
1078
+
1079
+ # Initialize timeout. It will be written later.
1080
+ @data_buffer.write_uint32(0, 22)
1081
+
1082
+ @data_buffer.write_uint16(field_count, 26)
1083
+ @data_buffer.write_uint16(0, 28)
1084
+
1085
+ @data_offset = MSG_TOTAL_HEADER_SIZE
1086
+ end
1087
+
976
1088
  def write_key(key, policy = nil)
977
1089
  # Write key into buffer.
978
1090
  if key.namespace
@@ -1110,15 +1222,6 @@ module Aerospike
1110
1222
  @data_offset += 1
1111
1223
  end
1112
1224
 
1113
- def write_predexp(predexp, predexp_size)
1114
- if predexp && predexp.size > 0
1115
- write_field_header(predexp_size, Aerospike::FieldType::FILTER_EXP)
1116
- @data_offset = Aerospike::PredExp.write(
1117
- predexp, @data_buffer, @data_offset
1118
- )
1119
- end
1120
- end
1121
-
1122
1225
  def write_filter_exp(exp, exp_size)
1123
1226
  unless exp.nil?
1124
1227
  write_field_header(exp_size, Aerospike::FieldType::FILTER_EXP)
@@ -1149,16 +1252,16 @@ module Aerospike
1149
1252
 
1150
1253
  def compress_buffer
1151
1254
  if @data_offset > COMPRESS_THRESHOLD
1152
- compressed = Zlib::deflate(@data_buffer.buf, Zlib::DEFAULT_COMPRESSION)
1255
+ compressed = Zlib.deflate(@data_buffer.buf, Zlib::DEFAULT_COMPRESSION)
1153
1256
 
1154
1257
  # write original size as header
1155
- proto_s = "%08d" % 0
1258
+ proto_s = format("%08d", 0)
1156
1259
  proto_s[0, 8] = [@data_offset].pack("q>")
1157
1260
  compressed.prepend(proto_s)
1158
1261
 
1159
1262
  # write proto
1160
1263
  proto = (compressed.size + 8) | Integer(CL_MSG_VERSION << 56) | Integer(AS_MSG_TYPE << 48)
1161
- proto_s = "%08d" % 0
1264
+ proto_s = format("%08d", 0)
1162
1265
  proto_s[0, 8] = [proto].pack("q>")
1163
1266
  compressed.prepend(proto_s)
1164
1267