aerospike 2.10.0 → 2.15.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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -1
  3. data/README.md +1 -1
  4. data/lib/aerospike.rb +20 -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/hll_operation.rb +200 -0
  9. data/lib/aerospike/cdt/hll_policy.rb +34 -0
  10. data/lib/aerospike/cdt/hll_write_flags.rb +53 -0
  11. data/lib/aerospike/cdt/list_operation.rb +1 -1
  12. data/lib/aerospike/cdt/map_operation.rb +1 -1
  13. data/lib/aerospike/cdt/map_order.rb +1 -1
  14. data/lib/aerospike/cdt/map_policy.rb +1 -1
  15. data/lib/aerospike/cdt/map_return_type.rb +1 -1
  16. data/lib/aerospike/cdt/map_write_mode.rb +1 -1
  17. data/lib/aerospike/client.rb +34 -18
  18. data/lib/aerospike/cluster.rb +139 -17
  19. data/lib/aerospike/cluster/partition.rb +1 -1
  20. data/lib/aerospike/cluster/partition_parser.rb +169 -0
  21. data/lib/aerospike/cluster/rack_parser.rb +117 -0
  22. data/lib/aerospike/command/admin_command.rb +1 -1
  23. data/lib/aerospike/command/batch_direct_command.rb +2 -1
  24. data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
  25. data/lib/aerospike/command/batch_direct_node.rb +3 -3
  26. data/lib/aerospike/command/batch_index_command.rb +11 -2
  27. data/lib/aerospike/command/batch_index_node.rb +2 -2
  28. data/lib/aerospike/command/batch_item.rb +1 -1
  29. data/lib/aerospike/command/command.rb +168 -11
  30. data/lib/aerospike/command/delete_command.rb +21 -5
  31. data/lib/aerospike/command/execute_command.rb +1 -1
  32. data/lib/aerospike/command/exists_command.rb +21 -5
  33. data/lib/aerospike/command/field_type.rb +3 -1
  34. data/lib/aerospike/command/multi_command.rb +55 -5
  35. data/lib/aerospike/command/operate_command.rb +6 -1
  36. data/lib/aerospike/command/read_command.rb +63 -20
  37. data/lib/aerospike/command/read_header_command.rb +18 -6
  38. data/lib/aerospike/command/roles.rb +1 -1
  39. data/lib/aerospike/command/single_command.rb +9 -3
  40. data/lib/aerospike/command/touch_command.rb +48 -4
  41. data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
  42. data/lib/aerospike/command/write_command.rb +13 -4
  43. data/lib/aerospike/connection/create.rb +1 -1
  44. data/lib/aerospike/features.rb +3 -1
  45. data/lib/aerospike/geo_json.rb +70 -1
  46. data/lib/aerospike/host.rb +1 -1
  47. data/lib/aerospike/info.rb +1 -1
  48. data/lib/aerospike/key.rb +1 -1
  49. data/lib/aerospike/language.rb +1 -1
  50. data/lib/aerospike/node.rb +21 -7
  51. data/lib/aerospike/node/rebalance.rb +50 -0
  52. data/lib/aerospike/node/refresh/info.rb +4 -1
  53. data/lib/aerospike/node/refresh/partitions.rb +6 -15
  54. data/lib/aerospike/node/refresh/racks.rb +47 -0
  55. data/lib/aerospike/node/refresh/reset.rb +1 -0
  56. data/lib/aerospike/node/verify/rebalance_generation.rb +43 -0
  57. data/lib/aerospike/node_validator.rb +4 -19
  58. data/lib/aerospike/operation.rb +8 -1
  59. data/lib/aerospike/policy/admin_policy.rb +1 -1
  60. data/lib/aerospike/policy/batch_policy.rb +1 -1
  61. data/lib/aerospike/policy/client_policy.rb +16 -1
  62. data/lib/aerospike/policy/commit_level.rb +1 -1
  63. data/lib/aerospike/policy/consistency_level.rb +1 -1
  64. data/lib/aerospike/policy/generation_policy.rb +1 -1
  65. data/lib/aerospike/policy/operate_policy.rb +1 -1
  66. data/lib/aerospike/policy/policy.rb +64 -2
  67. data/lib/aerospike/policy/priority.rb +1 -1
  68. data/lib/aerospike/policy/query_policy.rb +8 -1
  69. data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
  70. data/lib/aerospike/policy/record_exists_action.rb +1 -1
  71. data/lib/aerospike/policy/replica.rb +45 -0
  72. data/lib/aerospike/policy/scan_policy.rb +8 -1
  73. data/lib/aerospike/policy/write_policy.rb +1 -1
  74. data/lib/aerospike/query/filter.rb +1 -1
  75. data/lib/aerospike/query/pred_exp.rb +192 -0
  76. data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
  77. data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
  78. data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
  79. data/lib/aerospike/query/pred_exp/op.rb +27 -0
  80. data/lib/aerospike/query/pred_exp/regex.rb +32 -0
  81. data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
  82. data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
  83. data/lib/aerospike/query/query_command.rb +27 -1
  84. data/lib/aerospike/query/recordset.rb +5 -5
  85. data/lib/aerospike/query/scan_command.rb +1 -1
  86. data/lib/aerospike/query/statement.rb +12 -3
  87. data/lib/aerospike/query/stream_command.rb +1 -1
  88. data/lib/aerospike/record.rb +1 -1
  89. data/lib/aerospike/result_code.rb +26 -7
  90. data/lib/aerospike/socket/base.rb +4 -3
  91. data/lib/aerospike/task/execute_task.rb +1 -1
  92. data/lib/aerospike/task/index_task.rb +1 -1
  93. data/lib/aerospike/task/task.rb +1 -1
  94. data/lib/aerospike/task/udf_register_task.rb +1 -1
  95. data/lib/aerospike/task/udf_remove_task.rb +1 -1
  96. data/lib/aerospike/ttl.rb +1 -1
  97. data/lib/aerospike/udf.rb +1 -1
  98. data/lib/aerospike/user_role.rb +1 -1
  99. data/lib/aerospike/utils/buffer.rb +14 -4
  100. data/lib/aerospike/utils/packer.rb +1 -1
  101. data/lib/aerospike/utils/pool.rb +1 -1
  102. data/lib/aerospike/utils/unpacker.rb +7 -2
  103. data/lib/aerospike/value/particle_type.rb +2 -2
  104. data/lib/aerospike/value/value.rb +106 -29
  105. data/lib/aerospike/version.rb +1 -1
  106. metadata +22 -8
  107. data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
  108. data/lib/aerospike/cluster/partition_tokenizer_old.rb +0 -135
@@ -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.
@@ -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,6 +60,10 @@ module Aerospike
60
60
  # exists.
61
61
  KEY_EXISTS_ERROR = 5
62
62
 
63
+ # Bin already exists on a create-only operation.
64
+ BIN_EXISTS_ERROR = 6
65
+
66
+
63
67
  # Expected cluster ID was not received.
64
68
  CLUSTER_KEY_MISMATCH = 7
65
69
 
@@ -91,6 +95,9 @@ module Aerospike
91
95
  # Unsupported Server Feature (e.g. Scan + UDF)
92
96
  UNSUPPORTED_FEATURE = 16
93
97
 
98
+ # Bin not found on update-only operation.
99
+ BIN_NOT_FOUND = 17
100
+
94
101
  # Specified bin name does not exist in record.
95
102
  DEVICE_OVERLOAD = 18
96
103
 
@@ -116,6 +123,12 @@ module Aerospike
116
123
  # Enterprise-only feature not supported by the community edition
117
124
  ENTERPRISE_ONLY = 25
118
125
 
126
+ # The operation cannot be applied to the current bin value on the server.
127
+ OP_NOT_APPLICABLE = 26
128
+
129
+ # The transaction was not performed because the predexp was false.
130
+ FILTERED_OUT = 27
131
+
119
132
  # There are no more records left for query.
120
133
  QUERY_END = 50
121
134
 
@@ -167,9 +180,6 @@ module Aerospike
167
180
  # A user defined function returned an error code.
168
181
  UDF_BAD_RESPONSE = 100
169
182
 
170
- # The requested item in a large collection was not found.
171
- LARGE_ITEM_NOT_FOUND = 125
172
-
173
183
  # Secondary index already exists.
174
184
  INDEX_FOUND = 200
175
185
 
@@ -241,6 +251,9 @@ module Aerospike
241
251
  when KEY_EXISTS_ERROR
242
252
  "Key already exists"
243
253
 
254
+ when BIN_EXISTS_ERROR
255
+ "Bin already exists on a create-only operation"
256
+
244
257
  when CLUSTER_KEY_MISMATCH
245
258
  "Cluster key mismatch"
246
259
 
@@ -271,6 +284,9 @@ module Aerospike
271
284
  when UNSUPPORTED_FEATURE
272
285
  "Unsupported Server Feature"
273
286
 
287
+ when BIN_NOT_FOUND
288
+ "Bin not found on update-only operation"
289
+
274
290
  when DEVICE_OVERLOAD
275
291
  "Device overload"
276
292
 
@@ -295,6 +311,12 @@ module Aerospike
295
311
  when ENTERPRISE_ONLY
296
312
  "Enterprise-only feature not supported by community edition"
297
313
 
314
+ when OP_NOT_APPLICABLE
315
+ "The operation cannot be applied to the current bin value on the server."
316
+
317
+ when FILTERED_OUT
318
+ "The transaction was not performed because the predexp was false."
319
+
298
320
  when QUERY_END
299
321
  "Query end"
300
322
 
@@ -352,9 +374,6 @@ module Aerospike
352
374
  when UDF_BAD_RESPONSE
353
375
  "UDF d error"
354
376
 
355
- when LARGE_ITEM_NOT_FOUND
356
- "Large collection item not found"
357
-
358
377
  when INDEX_FOUND
359
378
  "Index already exists"
360
379
 
@@ -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.
@@ -25,13 +25,14 @@ module Aerospike
25
25
  @timeout = nil
26
26
  end
27
27
 
28
- def read(buffer, length)
28
+ def read(buffer, length, offset = 0)
29
29
  bytes_read = 0
30
30
  until bytes_read >= length
31
31
  result = read_from_socket(length - bytes_read)
32
- buffer.write_binary(result, bytes_read)
32
+ buffer.write_binary(result, offset + bytes_read)
33
33
  bytes_read += result.bytesize
34
34
  end
35
+ bytes_read
35
36
  end
36
37
 
37
38
  def read_from_socket(length)
@@ -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.
@@ -42,9 +42,9 @@ module Aerospike
42
42
  DEFAULT_BUFFER_SIZE = 16 * 1024
43
43
  MAX_BUFFER_SIZE = 10 * 1024 * 1024
44
44
 
45
- def initialize(size=DEFAULT_BUFFER_SIZE)
46
- @buf = "%0#{size}d" % 0
47
-
45
+ def initialize(size=DEFAULT_BUFFER_SIZE, buf = nil)
46
+ @buf = (buf ? buf : ("%0#{size}d" % 0))
47
+ @buf.force_encoding('binary')
48
48
  @slice_end = @buf.bytesize
49
49
  end
50
50
 
@@ -61,6 +61,10 @@ module Aerospike
61
61
  end
62
62
  alias_method :length, :size
63
63
 
64
+ def eat!(n)
65
+ @buf.replace(@buf[n..-1])
66
+ end
67
+
64
68
  def resize(length)
65
69
  if @buf.bytesize < length
66
70
  @buf.concat("%0#{length - @buf.bytesize}d" % 0)
@@ -156,6 +160,12 @@ module Aerospike
156
160
  @buf[0..@slice_end-1]
157
161
  end
158
162
 
163
+ def reset
164
+ for i in 0..@buf.size-1
165
+ @buf[i] = ' '
166
+ end
167
+ end
168
+
159
169
  def dump(from=nil, to=nil)
160
170
  from ||= 0
161
171
  to ||= @slice_end - 1
@@ -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.
@@ -36,7 +36,7 @@ module Aerospike
36
36
  #RTA_DICT = 15
37
37
  #RTA_APPEND_DICT = 16
38
38
  #RTA_APPEND_LIST = 17
39
- #LUA_BLOB = 18
39
+ HLL = 18
40
40
  MAP = 19
41
41
  LIST = 20
42
42
  GEOJSON = 23
@@ -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
  # #######################################/
@@ -496,6 +526,49 @@ module Aerospike
496
526
 
497
527
  end
498
528
 
529
+ # #######################################/
530
+
531
+ # HLLValue value. Encapsulates a HyperLogLog value.
532
+ # Supported by Aerospike server version 4.9 and later.
533
+ class HLLValue < Value #:nodoc:
534
+
535
+ def initialize(value)
536
+ @bytes = value
537
+ @bytes.force_encoding('binary')
538
+
539
+ self
540
+ end
541
+
542
+ def type
543
+ Aerospike::ParticleType::HLL
544
+ end
545
+
546
+ def get
547
+ self
548
+ end
549
+
550
+ def to_s
551
+ @bytes.to_s
552
+ end
553
+
554
+ def to_bytes
555
+ @bytes
556
+ end
557
+
558
+ def estimate_size
559
+ @bytes.bytesize
560
+ end
561
+
562
+ def write(buffer, offset)
563
+ buffer.write_binary(@bytes, offset)
564
+ end
565
+
566
+ def pack(packer)
567
+ packer.write(Aerospike::ParticleType::BLOB.chr + @bytes)
568
+ end
569
+
570
+ end
571
+
499
572
  #######################################
500
573
 
501
574
  def self.encoding
@@ -542,6 +615,10 @@ module Aerospike
542
615
  hdrsz = 1 + 2 + (ncells * 8)
543
616
  Aerospike::GeoJSON.new(buf.read(offset + hdrsz, length - hdrsz))
544
617
 
618
+ when Aerospike::ParticleType::HLL
619
+ bytes = buf.read(offset,length)
620
+ Aerospike::HLLValue.new(bytes)
621
+
545
622
  else
546
623
  nil
547
624
  end