aerospike 2.9.1 → 2.14.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -4
  3. data/README.md +1 -1
  4. data/lib/aerospike.rb +17 -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 +31 -17
  15. data/lib/aerospike/cluster.rb +139 -17
  16. data/lib/aerospike/cluster/partition.rb +1 -1
  17. data/lib/aerospike/cluster/partition_parser.rb +169 -0
  18. data/lib/aerospike/cluster/rack_parser.rb +117 -0
  19. data/lib/aerospike/command/admin_command.rb +1 -1
  20. data/lib/aerospike/command/batch_direct_command.rb +2 -1
  21. data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
  22. data/lib/aerospike/command/batch_direct_node.rb +3 -3
  23. data/lib/aerospike/command/batch_index_command.rb +11 -2
  24. data/lib/aerospike/command/batch_index_node.rb +2 -2
  25. data/lib/aerospike/command/batch_item.rb +1 -1
  26. data/lib/aerospike/command/command.rb +157 -11
  27. data/lib/aerospike/command/delete_command.rb +21 -5
  28. data/lib/aerospike/command/execute_command.rb +1 -1
  29. data/lib/aerospike/command/exists_command.rb +21 -5
  30. data/lib/aerospike/command/field_type.rb +3 -1
  31. data/lib/aerospike/command/multi_command.rb +55 -5
  32. data/lib/aerospike/command/operate_command.rb +6 -1
  33. data/lib/aerospike/command/read_command.rb +63 -20
  34. data/lib/aerospike/command/read_header_command.rb +18 -6
  35. data/lib/aerospike/command/roles.rb +1 -1
  36. data/lib/aerospike/command/single_command.rb +9 -3
  37. data/lib/aerospike/command/touch_command.rb +48 -4
  38. data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
  39. data/lib/aerospike/command/write_command.rb +13 -4
  40. data/lib/aerospike/connection/create.rb +1 -1
  41. data/lib/aerospike/features.rb +3 -1
  42. data/lib/aerospike/geo_json.rb +70 -1
  43. data/lib/aerospike/host.rb +1 -1
  44. data/lib/aerospike/info.rb +1 -1
  45. data/lib/aerospike/key.rb +1 -1
  46. data/lib/aerospike/language.rb +1 -1
  47. data/lib/aerospike/node.rb +21 -7
  48. data/lib/aerospike/node/rebalance.rb +50 -0
  49. data/lib/aerospike/node/refresh/info.rb +4 -1
  50. data/lib/aerospike/node/refresh/partitions.rb +6 -15
  51. data/lib/aerospike/node/refresh/racks.rb +47 -0
  52. data/lib/aerospike/node/refresh/reset.rb +1 -0
  53. data/lib/aerospike/node/verify/rebalance_generation.rb +43 -0
  54. data/lib/aerospike/node_validator.rb +45 -40
  55. data/lib/aerospike/operation.rb +6 -1
  56. data/lib/aerospike/policy/admin_policy.rb +1 -1
  57. data/lib/aerospike/policy/batch_policy.rb +1 -1
  58. data/lib/aerospike/policy/client_policy.rb +16 -1
  59. data/lib/aerospike/policy/commit_level.rb +1 -1
  60. data/lib/aerospike/policy/consistency_level.rb +1 -1
  61. data/lib/aerospike/policy/generation_policy.rb +1 -1
  62. data/lib/aerospike/policy/operate_policy.rb +1 -1
  63. data/lib/aerospike/policy/policy.rb +64 -2
  64. data/lib/aerospike/policy/priority.rb +1 -1
  65. data/lib/aerospike/policy/query_policy.rb +8 -1
  66. data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
  67. data/lib/aerospike/policy/record_exists_action.rb +1 -1
  68. data/lib/aerospike/policy/replica.rb +45 -0
  69. data/lib/aerospike/policy/scan_policy.rb +8 -1
  70. data/lib/aerospike/policy/write_policy.rb +1 -1
  71. data/lib/aerospike/query/filter.rb +1 -1
  72. data/lib/aerospike/query/pred_exp.rb +192 -0
  73. data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
  74. data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
  75. data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
  76. data/lib/aerospike/query/pred_exp/op.rb +27 -0
  77. data/lib/aerospike/query/pred_exp/regex.rb +32 -0
  78. data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
  79. data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
  80. data/lib/aerospike/query/query_command.rb +27 -1
  81. data/lib/aerospike/query/recordset.rb +5 -5
  82. data/lib/aerospike/query/scan_command.rb +1 -1
  83. data/lib/aerospike/query/statement.rb +12 -3
  84. data/lib/aerospike/query/stream_command.rb +1 -1
  85. data/lib/aerospike/record.rb +1 -1
  86. data/lib/aerospike/result_code.rb +13 -7
  87. data/lib/aerospike/socket/base.rb +4 -3
  88. data/lib/aerospike/task/execute_task.rb +1 -1
  89. data/lib/aerospike/task/index_task.rb +1 -1
  90. data/lib/aerospike/task/task.rb +1 -1
  91. data/lib/aerospike/task/udf_register_task.rb +1 -1
  92. data/lib/aerospike/task/udf_remove_task.rb +1 -1
  93. data/lib/aerospike/ttl.rb +1 -1
  94. data/lib/aerospike/udf.rb +1 -1
  95. data/lib/aerospike/user_role.rb +1 -1
  96. data/lib/aerospike/utils/buffer.rb +14 -4
  97. data/lib/aerospike/utils/packer.rb +1 -1
  98. data/lib/aerospike/utils/pool.rb +1 -1
  99. data/lib/aerospike/utils/unpacker.rb +7 -2
  100. data/lib/aerospike/value/particle_type.rb +1 -1
  101. data/lib/aerospike/value/value.rb +59 -29
  102. data/lib/aerospike/version.rb +1 -1
  103. metadata +19 -8
  104. data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
  105. 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.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.master_node(@partition)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_delete(@policy, @key)
38
42
  end
@@ -43,13 +47,25 @@ module Aerospike
43
47
 
44
48
  result_code = @data_buffer.read(13).ord & 0xFF
45
49
 
46
- if (result_code != 0) && (result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
47
- raise Aerospike::Exceptions::Aerospike.new(result_code)
50
+ if result_code == 0
51
+ @existed = true
52
+ return
48
53
  end
49
54
 
50
- @existed = (result_code == 0)
55
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
56
+ @existed = false
57
+ return
58
+ end
59
+
60
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
61
+ if @policy.fail_on_filtered_out
62
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
63
+ end
64
+ @existed = true
65
+ return
66
+ end
51
67
 
52
- empty_socket
68
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
53
69
  end
54
70
 
55
71
  end # class
@@ -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.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.read_node(@partition, @policy.replica, @sequence)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_exists(@policy, @key)
38
42
  end
@@ -43,13 +47,25 @@ module Aerospike
43
47
 
44
48
  result_code = @data_buffer.read(13).ord & 0xFF
45
49
 
46
- if (result_code != 0) && (result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
47
- raise Aerospike::Exceptions::Aerospike.new(result_code)
50
+ if result_code == 0
51
+ @exists = true
52
+ return
48
53
  end
49
54
 
50
- @exists = (result_code == 0)
55
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
56
+ @exists = false
57
+ return
58
+ end
59
+
60
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
61
+ if @policy.fail_on_filtered_out
62
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
63
+ end
64
+ @exists = true
65
+ return
66
+ end
51
67
 
52
- empty_socket
68
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
53
69
  end
54
70
 
55
71
  end # class
@@ -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.
@@ -31,6 +31,7 @@ module Aerospike
31
31
  TRAN_ID = 7 # user supplied transaction id, which is simply passed back
32
32
  SCAN_OPTIONS = 8
33
33
  SCAN_TIMEOUT = 9
34
+ RECORDS_PER_SECOND = 10
34
35
  INDEX_NAME = 21
35
36
  INDEX_RANGE = 22
36
37
  INDEX_FILTER = 23
@@ -43,6 +44,7 @@ module Aerospike
43
44
  UDF_OP = 33
44
45
  QUERY_BINLIST = 40
45
46
  BATCH_INDEX = 41
47
+ PREDEXP = 43
46
48
 
47
49
  end # module
48
50
 
@@ -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.
@@ -29,21 +29,57 @@ module Aerospike
29
29
  @valid = true
30
30
  @mutex = Mutex.new
31
31
 
32
+ @compressed_data_buffer = nil
33
+ @compressed_data_offset = nil
34
+
32
35
  self
33
36
  end
34
37
 
38
+ def get_node
39
+ @node
40
+ end
41
+
35
42
  def parse_result
36
43
  # Read socket into receive buffer one record at a time. Do not read entire receive size
37
44
  # because the receive buffer would be too big.
38
45
  status = true
39
46
 
40
47
  while status
48
+ @data_offset = 0
49
+ @compressed_data_buffer = nil
50
+
41
51
  # Read header.
42
52
  read_bytes(8)
43
53
 
44
54
  size = @data_buffer.read_int64(0)
45
55
  receive_size = size & 0xFFFFFFFFFFFF
46
56
 
57
+ # inflate if compressed
58
+ compressed_sz = compressed_size
59
+ if compressed_sz
60
+ begin
61
+ # read compressed msg header
62
+ @conn.read(@data_buffer, 8)
63
+
64
+ # read compressed message
65
+ @conn.read(@data_buffer, compressed_sz - 8)
66
+
67
+ # inflate the results
68
+ # TODO: reuse the current buffer
69
+ uncompressed = Zlib::inflate(@data_buffer.buf)
70
+ receive_size = uncompressed.size - 8
71
+
72
+ @compressed_data_buffer = Buffer.new(-1, uncompressed)
73
+ @compressed_data_offset = 0
74
+
75
+ # waste the first 8 header bytes
76
+ @compressed_data_buffer.eat!(8)
77
+ rescue => e
78
+ Aerospike.logger.error("parse result error: #{e}")
79
+ raise e
80
+ end
81
+ end
82
+
47
83
  if receive_size > 0
48
84
  status = parse_group(receive_size)
49
85
  else
@@ -59,10 +95,13 @@ module Aerospike
59
95
  read_bytes(MSG_REMAINING_HEADER_SIZE)
60
96
  result_code = @data_buffer.read(5).ord & 0xFF
61
97
 
62
- # The only valid server return codes are "ok" and "not found".
98
+ # The only valid server return codes are "ok", "not found" and "filtered out".
63
99
  # If other return codes are received, then abort the batch.
64
- if result_code != 0 && result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
65
- raise Aerospike::Exceptions::Aerospike.new(result_code)
100
+ if result_code != 0
101
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR || result_code == Aerospike::ResultCode::FILTERED_OUT
102
+ else
103
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
104
+ end
66
105
  end
67
106
 
68
107
  # If cmd is the end marker of the response, do not proceed further
@@ -150,7 +189,13 @@ module Aerospike
150
189
  @data_buffer = Buffer.new(length)
151
190
  end
152
191
 
153
- @conn.read(@data_buffer, length)
192
+ if compressed?
193
+ @data_buffer.write_binary(@compressed_data_buffer.buf[@compressed_data_offset...@compressed_data_offset+length], 0)
194
+ @compressed_data_offset += length
195
+ else
196
+ @conn.read(@data_buffer, length)
197
+ end
198
+
154
199
  @data_offset += length
155
200
  end
156
201
 
@@ -169,6 +214,11 @@ module Aerospike
169
214
  res
170
215
  end
171
216
 
217
+ def compressed?
218
+ @compressed_data_buffer != nil
219
+ end
220
+
221
+
172
222
  end # class
173
223
 
174
224
  end # module
@@ -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.
@@ -28,6 +28,11 @@ module Aerospike
28
28
  @operations = operations
29
29
  end
30
30
 
31
+ def get_node
32
+ @cluster.master_node(@partition)
33
+ end
34
+
35
+
31
36
  def write_bins
32
37
  @operations.select{|op| op.op_type == Aerospike::Operation::WRITE}.map(&:bin).compact
33
38
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2017 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.
@@ -15,6 +15,8 @@
15
15
  # License for the specific language governing permissions and limitations under
16
16
  # the License.
17
17
 
18
+ require 'zlib'
19
+
18
20
  require 'aerospike/record'
19
21
 
20
22
  require 'aerospike/command/single_command'
@@ -39,6 +41,10 @@ module Aerospike
39
41
  self
40
42
  end
41
43
 
44
+ def get_node
45
+ @cluster.read_node(@partition, @policy.replica, @sequence)
46
+ end
47
+
42
48
  def write_buffer
43
49
  set_read(@policy, @key, @bin_names)
44
50
  end
@@ -46,12 +52,40 @@ module Aerospike
46
52
  def parse_result
47
53
  # Read header.
48
54
  begin
49
- @conn.read(@data_buffer, MSG_TOTAL_HEADER_SIZE)
55
+ @conn.read(@data_buffer, 8)
50
56
  rescue => e
51
57
  Aerospike.logger.error("parse result error: #{e}")
52
58
  raise e
53
59
  end
54
60
 
61
+ # inflate if compressed
62
+ compressed_sz = compressed_size
63
+ if compressed_sz
64
+ begin
65
+ # waste 8 size bytes
66
+ @conn.read(@data_buffer, 8)
67
+
68
+ # read compressed message
69
+ @conn.read(@data_buffer, compressed_sz - 8)
70
+
71
+ # inflate the results
72
+ # TODO: reuse the current buffer
73
+ uncompressed = Zlib::inflate(@data_buffer.buf)
74
+
75
+ @data_buffer = Buffer.new(-1, uncompressed)
76
+ rescue => e
77
+ Aerospike.logger.error("parse result error: #{e}")
78
+ raise e
79
+ end
80
+ else
81
+ begin
82
+ bytes_read = @conn.read(@data_buffer, MSG_TOTAL_HEADER_SIZE - 8, 8)
83
+ rescue => e
84
+ Aerospike.logger.error("parse result error: #{e}")
85
+ raise e
86
+ end
87
+ end
88
+
55
89
  # A number of these are commented out because we just don't care enough to read
56
90
  # that section of the header. If we do care, uncomment and check!
57
91
  sz = @data_buffer.read_int64(0)
@@ -64,7 +98,9 @@ module Aerospike
64
98
  receive_size = (sz & 0xFFFFFFFFFFFF) - header_length
65
99
 
66
100
  # Read remaining message bytes.
67
- if receive_size > 0
101
+ if compressed_sz
102
+ @data_buffer.eat!(MSG_TOTAL_HEADER_SIZE)
103
+ elsif receive_size > 0
68
104
  size_buffer_sz(receive_size)
69
105
 
70
106
  begin
@@ -76,29 +112,36 @@ module Aerospike
76
112
 
77
113
  end
78
114
 
79
- if result_code != 0
80
- return nil if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
81
- return nil if result_code == Aerospike::ResultCode::LARGE_ITEM_NOT_FOUND
82
- if result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE
83
- begin
84
- @record = parse_record(op_count, field_count, generation, expiration)
85
- handle_udf_error(result_code)
86
- rescue => e
87
- Aerospike.logger.error("UDF execution error: #{e}")
88
- raise e
89
- end
90
-
115
+ if result_code == 0
116
+ if op_count == 0
117
+ @record = Record.new(@node, @key, nil, generation, expiration)
118
+ return
91
119
  end
92
-
93
- raise Aerospike::Exceptions::Aerospike.new(result_code)
120
+
121
+ @record = parse_record(op_count, field_count, generation, expiration)
122
+ return
94
123
  end
95
124
 
96
- if op_count == 0
97
- @record = Record.new(@node, @key, nil, generation, expiration)
125
+ return nil if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
126
+
127
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
128
+ if @policy.fail_on_filtered_out
129
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
130
+ end
98
131
  return
99
132
  end
100
133
 
101
- @record = parse_record(op_count, field_count, generation, expiration)
134
+ if result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE
135
+ begin
136
+ @record = parse_record(op_count, field_count, generation, expiration)
137
+ handle_udf_error(result_code)
138
+ rescue => e
139
+ Aerospike.logger.error("UDF execution error: #{e}")
140
+ raise e
141
+ end
142
+ end
143
+
144
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
102
145
  end
103
146
 
104
147
  def handle_udf_error(result_code)
@@ -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.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.read_node(@partition, @policy.replica, @sequence)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_read_header(@policy, @key)
38
42
  end
@@ -47,15 +51,23 @@ module Aerospike
47
51
  generation = @data_buffer.read_int32(14)
48
52
  expiration = @data_buffer.read_int32(18)
49
53
  @record = Record.new(@node, @key, nil, generation, expiration)
50
- else
51
- if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
52
- @record = nil
53
- else
54
+ return
55
+ end
56
+
57
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
58
+ @record = nil
59
+ return
60
+ end
61
+
62
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
63
+ @record = nil
64
+ if @policy.fail_on_filtered_out
54
65
  raise Aerospike::Exceptions::Aerospike.new(result_code)
55
66
  end
67
+ return
56
68
  end
57
69
 
58
- empty_socket
70
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
59
71
  end
60
72
 
61
73
  end # class
@@ -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,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.
@@ -27,12 +27,18 @@ module Aerospike
27
27
  @cluster = cluster
28
28
  @key = key
29
29
 
30
- node = cluster.get_node_for_key(key)
31
- super(node)
30
+ @partition = Partition.new_by_key(key)
31
+
32
+ super()
32
33
  end
33
34
 
34
35
  protected
35
36
 
37
+ def get_node
38
+ # abstract method
39
+ raise Aerospike::Exceptions::InvalidNode
40
+ end
41
+
36
42
  def empty_socket
37
43
  # There should not be any more bytes.
38
44
  # Empty the socket to be safe.