aerospike 2.9.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -4
  3. data/README.md +1 -1
  4. data/lib/aerospike.rb +12 -4
  5. data/lib/aerospike/aerospike_exception.rb +7 -1
  6. data/lib/aerospike/atomic/atomic.rb +1 -1
  7. data/lib/aerospike/bin.rb +1 -1
  8. data/lib/aerospike/cdt/list_operation.rb +1 -1
  9. data/lib/aerospike/cdt/map_operation.rb +1 -1
  10. data/lib/aerospike/cdt/map_order.rb +1 -1
  11. data/lib/aerospike/cdt/map_policy.rb +1 -1
  12. data/lib/aerospike/cdt/map_return_type.rb +1 -1
  13. data/lib/aerospike/cdt/map_write_mode.rb +1 -1
  14. data/lib/aerospike/client.rb +10 -11
  15. data/lib/aerospike/cluster.rb +92 -17
  16. data/lib/aerospike/cluster/partition.rb +1 -1
  17. data/lib/aerospike/cluster/partition_parser.rb +169 -0
  18. data/lib/aerospike/command/admin_command.rb +2 -3
  19. data/lib/aerospike/command/batch_direct_command.rb +1 -1
  20. data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
  21. data/lib/aerospike/command/batch_direct_node.rb +3 -3
  22. data/lib/aerospike/command/batch_index_command.rb +10 -2
  23. data/lib/aerospike/command/batch_index_node.rb +2 -2
  24. data/lib/aerospike/command/batch_item.rb +1 -1
  25. data/lib/aerospike/command/command.rb +102 -11
  26. data/lib/aerospike/command/delete_command.rb +21 -5
  27. data/lib/aerospike/command/execute_command.rb +1 -1
  28. data/lib/aerospike/command/exists_command.rb +21 -5
  29. data/lib/aerospike/command/field_type.rb +3 -1
  30. data/lib/aerospike/command/multi_command.rb +11 -4
  31. data/lib/aerospike/command/operate_command.rb +6 -1
  32. data/lib/aerospike/command/read_command.rb +29 -18
  33. data/lib/aerospike/command/read_header_command.rb +18 -6
  34. data/lib/aerospike/command/roles.rb +1 -1
  35. data/lib/aerospike/command/single_command.rb +9 -3
  36. data/lib/aerospike/command/touch_command.rb +14 -3
  37. data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
  38. data/lib/aerospike/command/write_command.rb +13 -4
  39. data/lib/aerospike/connection/create.rb +1 -1
  40. data/lib/aerospike/features.rb +1 -1
  41. data/lib/aerospike/geo_json.rb +70 -1
  42. data/lib/aerospike/host.rb +1 -1
  43. data/lib/aerospike/info.rb +1 -1
  44. data/lib/aerospike/key.rb +1 -1
  45. data/lib/aerospike/language.rb +1 -1
  46. data/lib/aerospike/node.rb +3 -6
  47. data/lib/aerospike/node/refresh/partitions.rb +6 -15
  48. data/lib/aerospike/node_validator.rb +45 -40
  49. data/lib/aerospike/operation.rb +6 -1
  50. data/lib/aerospike/policy/admin_policy.rb +1 -1
  51. data/lib/aerospike/policy/batch_policy.rb +1 -1
  52. data/lib/aerospike/policy/client_policy.rb +1 -1
  53. data/lib/aerospike/policy/commit_level.rb +1 -1
  54. data/lib/aerospike/policy/consistency_level.rb +1 -1
  55. data/lib/aerospike/policy/generation_policy.rb +1 -1
  56. data/lib/aerospike/policy/operate_policy.rb +1 -1
  57. data/lib/aerospike/policy/policy.rb +57 -3
  58. data/lib/aerospike/policy/priority.rb +1 -1
  59. data/lib/aerospike/policy/query_policy.rb +8 -1
  60. data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
  61. data/lib/aerospike/policy/record_exists_action.rb +1 -1
  62. data/lib/aerospike/policy/replica.rb +38 -0
  63. data/lib/aerospike/policy/scan_policy.rb +8 -1
  64. data/lib/aerospike/policy/write_policy.rb +1 -1
  65. data/lib/aerospike/query/filter.rb +1 -1
  66. data/lib/aerospike/query/pred_exp.rb +192 -0
  67. data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
  68. data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
  69. data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
  70. data/lib/aerospike/query/pred_exp/op.rb +27 -0
  71. data/lib/aerospike/query/pred_exp/regex.rb +32 -0
  72. data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
  73. data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
  74. data/lib/aerospike/query/query_command.rb +27 -1
  75. data/lib/aerospike/query/recordset.rb +5 -5
  76. data/lib/aerospike/query/scan_command.rb +1 -1
  77. data/lib/aerospike/query/statement.rb +12 -3
  78. data/lib/aerospike/query/stream_command.rb +9 -10
  79. data/lib/aerospike/record.rb +1 -1
  80. data/lib/aerospike/result_code.rb +13 -20
  81. data/lib/aerospike/socket/base.rb +1 -1
  82. data/lib/aerospike/task/execute_task.rb +1 -1
  83. data/lib/aerospike/task/index_task.rb +1 -1
  84. data/lib/aerospike/task/task.rb +1 -1
  85. data/lib/aerospike/task/udf_register_task.rb +1 -1
  86. data/lib/aerospike/task/udf_remove_task.rb +1 -1
  87. data/lib/aerospike/ttl.rb +1 -1
  88. data/lib/aerospike/udf.rb +1 -1
  89. data/lib/aerospike/user_role.rb +1 -1
  90. data/lib/aerospike/utils/buffer.rb +1 -1
  91. data/lib/aerospike/utils/packer.rb +1 -1
  92. data/lib/aerospike/utils/pool.rb +1 -1
  93. data/lib/aerospike/utils/unpacker.rb +7 -2
  94. data/lib/aerospike/value/particle_type.rb +1 -1
  95. data/lib/aerospike/value/value.rb +59 -29
  96. data/lib/aerospike/version.rb +1 -1
  97. metadata +15 -8
  98. data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
  99. data/lib/aerospike/cluster/partition_tokenizer_old.rb +0 -135
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aerospike
4
+ class PredExp
5
+ class StringValue < PredExp
6
+ def initialize(value, type)
7
+ @value = value
8
+ @type = type
9
+ end
10
+
11
+ def estimate_size
12
+ @value.bytesize + 6
13
+ end
14
+
15
+ def write(buffer, offset)
16
+ buffer.write_int16(@type, offset)
17
+ offset += 2
18
+
19
+ buffer.write_int32(@value.bytesize, offset)
20
+ offset += 4
21
+
22
+ len = buffer.write_binary(@value, offset)
23
+ offset += len
24
+
25
+ offset
26
+ end
27
+ end
28
+ end
29
+ 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.
@@ -35,6 +35,7 @@ module Aerospike
35
35
  fieldCount = 0
36
36
  filterSize = 0
37
37
  binNameSize = 0
38
+ predSize = 0
38
39
 
39
40
  begin_cmd
40
41
 
@@ -81,6 +82,11 @@ module Aerospike
81
82
  fieldCount+=1
82
83
  end
83
84
  else
85
+ if @policy.records_per_second > 0
86
+ @data_offset += 4 + FIELD_HEADER_SIZE
87
+ fieldCount += 1
88
+ end
89
+
84
90
  # Calling query with no filters is more efficiently handled by a primary index scan.
85
91
  # Estimate scan options size.
86
92
  @data_offset += (2 + FIELD_HEADER_SIZE)
@@ -92,6 +98,15 @@ module Aerospike
92
98
  @data_offset += 8 + FIELD_HEADER_SIZE
93
99
  fieldCount+=1
94
100
 
101
+ predexp = @policy.predexp || @statement.predexp
102
+
103
+ if predexp
104
+ @data_offset += FIELD_HEADER_SIZE
105
+ predSize = Aerospike::PredExp.estimate_size(predexp)
106
+ @data_offset += predSize
107
+ fieldCount += 1
108
+ end
109
+
95
110
  if @statement.function_name
96
111
  @data_offset += FIELD_HEADER_SIZE + 1 # udf type
97
112
  @data_offset += @statement.package_name.bytesize + FIELD_HEADER_SIZE
@@ -162,6 +177,10 @@ module Aerospike
162
177
  end
163
178
  end
164
179
  else
180
+ if @policy.records_per_second > 0
181
+ write_field_int(@policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
182
+ end
183
+
165
184
  # Calling query with no filters is more efficiently handled by a primary index scan.
166
185
  write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
167
186
  priority = @policy.priority.ord
@@ -176,6 +195,13 @@ module Aerospike
176
195
  @data_buffer.write_int64(@statement.task_id, @data_offset)
177
196
  @data_offset += 8
178
197
 
198
+ if predexp
199
+ write_field_header(predSize, Aerospike::FieldType::PREDEXP)
200
+ @data_offset = Aerospike::PredExp.write(
201
+ predexp, @data_buffer, @data_offset
202
+ )
203
+ end
204
+
179
205
  if @statement.function_name
180
206
  write_field_header(1, Aerospike::FieldType::UDF_OP)
181
207
  if @statement.return_data
@@ -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.
@@ -20,7 +20,7 @@ module Aerospike
20
20
  # a producer is a thread that fetches records from one node and puts them on this queue
21
21
  # a consumer fetches records from this queue
22
22
  # so the production and the consumptoin are decoupled
23
- # there can be an unlimited count of producer threads and consumer threads
23
+ # there can be an unlimited count of producer threads and consumer threads
24
24
  class Recordset
25
25
 
26
26
  attr_reader :records
@@ -29,7 +29,7 @@ module Aerospike
29
29
  queue_size = thread_count if queue_size < thread_count
30
30
  @records = SizedQueue.new(queue_size)
31
31
 
32
- # holds the count of active threads.
32
+ # holds the count of active threads.
33
33
  # when it reaches zero it means the whole operations of fetching records from server nodes is finished
34
34
  @active_threads = Atomic.new(thread_count)
35
35
 
@@ -48,7 +48,7 @@ module Aerospike
48
48
  # if the operation is not finished and the queue is empty it blocks and waits for new records
49
49
  # it sets the exception if it reaches the EOF mark, and returns nil
50
50
  # EOF means the operation has finished and no more records are comming from server nodes
51
- # it re-raises the exception occurred in threads, or which was set after reaching the EOF in the previous call
51
+ # it re-raises the exception occurred in threads, or which was set after reaching the EOF in the previous call
52
52
  def next_record
53
53
  raise @thread_exception.get unless @thread_exception.get.nil?
54
54
 
@@ -76,7 +76,7 @@ module Aerospike
76
76
 
77
77
  # this is called by a thread who faced an exception to singnal to terminate the whole operation
78
78
  # it also may be called by the user to terminate the command in the middle of fetching records from server nodes
79
- # it clears the queue so that if any threads are waiting for the queue get unblocked and find out about the cancellation
79
+ # it clears the queue so that if any threads are waiting for the queue get unblocked and find out about the cancellation
80
80
  def cancel(expn=nil)
81
81
  set_exception(expn)
82
82
  @cancelled.set(true)
@@ -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,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.
@@ -20,7 +20,7 @@ module Aerospike
20
20
 
21
21
  attr_accessor :namespace, :set_name, :index_name, :bin_names, :task_id
22
22
  attr_accessor :filters, :package_name, :function_name, :function_args
23
- attr_accessor :return_data
23
+ attr_accessor :predexp, :return_data
24
24
 
25
25
  def initialize(namespace, set_name, bin_names=[])
26
26
  # Namespace determines query Namespace
@@ -43,6 +43,16 @@ module Aerospike
43
43
  # aggregation function.
44
44
  @filters = []
45
45
 
46
+ # Predicate expressions in postfix notation. If the expression is evaluated to false,
47
+ # the record will be ommited in the results.
48
+ #
49
+ # This method is redundant because PredExp can now be set in the base Policy for
50
+ # any transaction (including queries).
51
+ #
52
+ # NOTE : Policy.predexp takes precedence to this value. This value will be
53
+ # deprecated in the future.
54
+ @predexp = nil
55
+
46
56
  @package_name = nil
47
57
  @function_name = nil
48
58
  @function_args = nil
@@ -76,5 +86,4 @@ module Aerospike
76
86
  RAND_MAX = 2**63
77
87
 
78
88
  end # class
79
-
80
89
  end
@@ -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.
@@ -36,15 +36,14 @@ module Aerospike
36
36
 
37
37
  # The only valid server return codes are "ok" and "not found".
38
38
  # If other return codes are received, then abort the batch.
39
- if result_code != 0
40
- # if there is no recordset defined, it means this is an Execute UDF On Query command
41
- # return successfully
42
- if (@recordset == nil) && (result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
43
- # consume the rest of the input buffer from the socket
44
- read_bytes(receive_size - @data_offset) if @data_offset < receive_size
45
-
46
- return nil
47
- end
39
+ case result_code
40
+ when Aerospike::ResultCode::OK
41
+ # noop
42
+ when Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
43
+ # consume the rest of the input buffer from the socket
44
+ read_bytes(receive_size - @data_offset) if @data_offset < receive_size
45
+ return nil
46
+ else
48
47
  raise Aerospike::Exceptions::Aerospike.new(result_code)
49
48
  end
50
49
 
@@ -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,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.
@@ -60,10 +60,6 @@ module Aerospike
60
60
  # exists.
61
61
  KEY_EXISTS_ERROR = 5
62
62
 
63
- # On create-only (write unique) operations on a bin that already
64
- # exists.
65
- BIN_EXISTS_ERROR = 6
66
-
67
63
  # Expected cluster ID was not received.
68
64
  CLUSTER_KEY_MISMATCH = 7
69
65
 
@@ -95,9 +91,6 @@ module Aerospike
95
91
  # Unsupported Server Feature (e.g. Scan + UDF)
96
92
  UNSUPPORTED_FEATURE = 16
97
93
 
98
- # Specified bin name does not exist in record.
99
- BIN_NOT_FOUND = 17
100
-
101
94
  # Specified bin name does not exist in record.
102
95
  DEVICE_OVERLOAD = 18
103
96
 
@@ -123,6 +116,12 @@ module Aerospike
123
116
  # Enterprise-only feature not supported by the community edition
124
117
  ENTERPRISE_ONLY = 25
125
118
 
119
+ # The operation cannot be applied to the current bin value on the server.
120
+ OP_NOT_APPLICABLE = 26
121
+
122
+ # The transaction was not performed because the predexp was false.
123
+ FILTERED_OUT = 27
124
+
126
125
  # There are no more records left for query.
127
126
  QUERY_END = 50
128
127
 
@@ -174,9 +173,6 @@ module Aerospike
174
173
  # A user defined function returned an error code.
175
174
  UDF_BAD_RESPONSE = 100
176
175
 
177
- # The requested item in a large collection was not found.
178
- LARGE_ITEM_NOT_FOUND = 125
179
-
180
176
  # Secondary index already exists.
181
177
  INDEX_FOUND = 200
182
178
 
@@ -248,9 +244,6 @@ module Aerospike
248
244
  when KEY_EXISTS_ERROR
249
245
  "Key already exists"
250
246
 
251
- when BIN_EXISTS_ERROR
252
- "Bin already exists"
253
-
254
247
  when CLUSTER_KEY_MISMATCH
255
248
  "Cluster key mismatch"
256
249
 
@@ -281,9 +274,6 @@ module Aerospike
281
274
  when UNSUPPORTED_FEATURE
282
275
  "Unsupported Server Feature"
283
276
 
284
- when BIN_NOT_FOUND
285
- "Bin not found"
286
-
287
277
  when DEVICE_OVERLOAD
288
278
  "Device overload"
289
279
 
@@ -308,6 +298,12 @@ module Aerospike
308
298
  when ENTERPRISE_ONLY
309
299
  "Enterprise-only feature not supported by community edition"
310
300
 
301
+ when OP_NOT_APPLICABLE
302
+ "The operation cannot be applied to the current bin value on the server."
303
+
304
+ when FILTERED_OUT
305
+ "The transaction was not performed because the predexp was false."
306
+
311
307
  when QUERY_END
312
308
  "Query end"
313
309
 
@@ -365,9 +361,6 @@ module Aerospike
365
361
  when UDF_BAD_RESPONSE
366
362
  "UDF d error"
367
363
 
368
- when LARGE_ITEM_NOT_FOUND
369
- "Large collection item not found"
370
-
371
364
  when INDEX_FOUND
372
365
  "Index already exists"
373
366
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2018 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -1,4 +1,4 @@
1
- # Copyright 2013-2017 Aerospike, Inc.
1
+ # Copyright 2013-2020 Aerospike, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -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,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,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,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,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -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,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,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Copyright 2014-2018 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # Copyright 2014-2018 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,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2018 Aerospike, Inc.
2
+ # Copyright 2016-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -85,7 +85,12 @@ module Aerospike
85
85
  def normalize_elem(elem)
86
86
  case elem
87
87
  when String
88
- elem[1..-1].encode(Aerospike.encoding)
88
+ ptype = elem.ord
89
+ value = elem[1..-1]
90
+ if (ptype == ParticleType::STRING)
91
+ value.encode!(Aerospike.encoding)
92
+ end
93
+ value
89
94
  when Array
90
95
  normalize_strings_in_array(elem)
91
96
  when Hash
@@ -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
  # Licensed under the Apache License, Version 2.0 (the "License")
5
5
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Copyright 2014-2018 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -22,14 +22,11 @@ require 'aerospike/aerospike_exception'
22
22
  module Aerospike
23
23
  # Polymorphic value classes used to efficiently serialize objects into the wire protocol.
24
24
  class Value #:nodoc:
25
- INTEGER_RANGE = Range.new(-2**63, 2**63 - 1).freeze
26
25
 
27
26
  def self.of(value)
28
27
  case value
29
- when nil
30
- res = NULL
31
28
  when Integer
32
- if INTEGER_RANGE.cover?(value)
29
+ if value.bit_length < 64
33
30
  res = IntegerValue.new(value)
34
31
  else
35
32
  # big nums > 2**63 are not supported
@@ -49,6 +46,8 @@ module Aerospike
49
46
  res = ListValue.new(value)
50
47
  when GeoJSON
51
48
  res = GeoJSONValue.new(value)
49
+ when nil
50
+ res = NULL
52
51
  else
53
52
  # throw an exception for anything that is not supported.
54
53
  raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported.")
@@ -57,6 +56,22 @@ module Aerospike
57
56
  res
58
57
  end
59
58
 
59
+ def self.validate_hash_key(value)
60
+ case value
61
+ when Integer
62
+ if value.bit_length >= 64
63
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported as hash key.")
64
+ end
65
+ when Float
66
+ when String
67
+ when Symbol
68
+ when nil
69
+ else
70
+ # throw an exception for anything that is not supported.
71
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::TYPE_NOT_SUPPORTED, "Value type #{value.class} not supported as hash key.")
72
+ end
73
+ end
74
+
60
75
  end # Value
61
76
 
62
77
  # Empty value.
@@ -137,7 +152,7 @@ module Aerospike
137
152
  end
138
153
  end
139
154
 
140
- INFINITY = InfinityValue.new.freeze
155
+ INFINITY = Value::INFINITY = InfinityValue.new.freeze
141
156
 
142
157
  # Wildcard value.
143
158
  class WildcardValue < Value #:nodoc:
@@ -178,7 +193,7 @@ module Aerospike
178
193
  end
179
194
  end
180
195
 
181
- WILDCARD = WildcardValue.new.freeze
196
+ WILDCARD = Value::WILDCARD = WildcardValue.new.freeze
182
197
 
183
198
  # Byte array value.
184
199
  class BytesValue < Value #:nodoc:
@@ -356,21 +371,16 @@ module Aerospike
356
371
  class ListValue < Value #:nodoc:
357
372
 
358
373
  def initialize(list)
359
- @list = list || nil
360
- Packer.use do |packer|
361
- pack(packer)
362
- @bytes = packer.bytes
363
- end
364
- self
374
+ @list = list || []
365
375
  end
366
376
 
367
377
  def estimate_size
368
- @bytes.bytesize
378
+ bytes.bytesize
369
379
  end
370
380
 
371
381
  def write(buffer, offset)
372
- buffer.write_binary(@bytes, offset)
373
- @bytes.bytesize
382
+ buffer.write_binary(bytes, offset)
383
+ bytes.bytesize
374
384
  end
375
385
 
376
386
  def pack(packer)
@@ -389,13 +399,26 @@ module Aerospike
389
399
  end
390
400
 
391
401
  def to_bytes
392
- @bytes
402
+ bytes
393
403
  end
394
404
 
395
405
  def to_s
396
406
  @list.map{|v| v.to_s}.to_s
397
407
  end
398
408
 
409
+ private
410
+
411
+ def bytes
412
+ return @bytes if @bytes
413
+
414
+ Packer.use do |packer|
415
+ pack(packer)
416
+ @bytes = packer.bytes
417
+ end
418
+
419
+ @bytes
420
+ end
421
+
399
422
  end
400
423
 
401
424
  # #######################################/
@@ -406,28 +429,22 @@ module Aerospike
406
429
 
407
430
  def initialize(vmap)
408
431
  @vmap = vmap || {}
409
-
410
- Packer.use do |packer|
411
- pack(packer)
412
- @bytes = packer.bytes
413
- end
414
-
415
- self
416
432
  end
417
433
 
418
434
  def estimate_size
419
- @bytes.bytesize
435
+ bytes.bytesize
420
436
  end
421
437
 
422
438
  def write(buffer, offset)
423
- buffer.write_binary(@bytes, offset)
424
- @bytes.bytesize
439
+ buffer.write_binary(bytes, offset)
440
+ bytes.bytesize
425
441
  end
426
442
 
427
443
  def pack(packer)
428
444
  packer.write_map_header(@vmap.length)
429
- # @vmap.each do |key, val|
430
445
  for key, val in @vmap
446
+ Value.validate_hash_key(key)
447
+
431
448
  Value.of(key).pack(packer)
432
449
  Value.of(val).pack(packer)
433
450
  end
@@ -442,13 +459,26 @@ module Aerospike
442
459
  end
443
460
 
444
461
  def to_bytes
445
- @bytes
462
+ bytes
446
463
  end
447
464
 
448
465
  def to_s
449
466
  @vmap.map{|k, v| "#{k.to_s} => #{v.to_s}" }.to_s
450
467
  end
451
468
 
469
+ private
470
+
471
+ def bytes
472
+ return @bytes if @bytes
473
+
474
+ Packer.use do |packer|
475
+ pack(packer)
476
+ @bytes = packer.bytes
477
+ end
478
+
479
+ @bytes
480
+ end
481
+
452
482
  end
453
483
 
454
484
  # #######################################/