aerospike 2.10.0 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
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