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
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
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 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,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.
@@ -33,7 +33,6 @@ module Aerospike
33
33
  @name = nv.name
34
34
  @aliases = Atomic.new(nv.aliases)
35
35
  @host = nv.host
36
- @use_new_info = Atomic.new(nv.use_new_info)
37
36
  @features = nv.features
38
37
  @cluster_name = nv.cluster_name
39
38
 
@@ -52,6 +51,8 @@ module Aerospike
52
51
  @active = Atomic.new(true)
53
52
  @failures = Atomic.new(0)
54
53
 
54
+ @replica_index = Atomic.new(0)
55
+
55
56
  @connections = ::Aerospike::ConnectionPool.new(cluster, host)
56
57
  end
57
58
 
@@ -178,10 +179,6 @@ module Aerospike
178
179
  end
179
180
  alias eql? ==
180
181
 
181
- def use_new_info?
182
- @use_new_info.value
183
- end
184
-
185
182
  def hash
186
183
  @name.hash
187
184
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Aerospike, Inc.
3
+ # Copyright 2018-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -25,24 +25,15 @@ module Aerospike
25
25
  def call(node, peers)
26
26
  return unless should_refresh?(node, peers)
27
27
 
28
- node.cluster.update_partitions(tokenizer(node), node)
28
+ Aerospike.logger.info("Updating partitions for node #{node.name}")
29
+ conn = node.tend_connection
30
+ parser = PartitionParser.new(node, conn)
31
+ node.cluster.update_partitions(parser)
29
32
  rescue ::Aerospike::Exceptions::Aerospike => e
30
- node.tend_connection.close
33
+ conn.close
31
34
  Refresh::Failed.(node, e)
32
35
  end
33
36
 
34
- # Return correct tokenizer depending on version
35
- def tokenizer(node)
36
- conn = node.tend_connection
37
- if node.use_new_info?
38
- Aerospike.logger.info("Updating partitions for node #{node.name} using new protocol")
39
- PartitionTokenizerNew.new(conn)
40
- else
41
- Aerospike.logger.info("Updating partitions for node #{node.name} using old protocol")
42
- PartitionTokenizerOld.new(conn)
43
- end
44
- end
45
-
46
37
  # Do not refresh partitions when node connection has already failed
47
38
  # during this cluster tend iteration. Also, avoid "split cluster"
48
39
  # case where this node thinks it's a 1-node cluster. Unchecked, such
@@ -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.
@@ -19,54 +19,57 @@
19
19
 
20
20
  module Aerospike
21
21
  class NodeValidator # :nodoc:
22
- VERSION_REGEXP = /(?<v1>\d+)\.(?<v2>\d+)\.(?<v3>\d+).*/.freeze
23
22
 
24
- attr_reader :host, :aliases, :name, :use_new_info, :features, :cluster_name, :tls_options, :conn
23
+ attr_reader :host, :aliases, :name, :features, :cluster_name, :tls_options, :conn
25
24
 
26
25
  def initialize(cluster, host, timeout, cluster_name, tls_options = {})
27
26
  @cluster = cluster
28
- @use_new_info = true
29
27
  @features = Set.new
30
28
  @host = host
31
29
  @cluster_name = cluster_name
32
30
  @tls_options = tls_options
33
31
 
34
- set_aliases(host)
35
- set_address(timeout)
32
+ @aliases = []
33
+
34
+ resolve(host.name).each do |address|
35
+ @aliases += get_hosts(address)
36
+ end
36
37
  end
37
38
 
38
39
  private
39
40
 
40
- def set_aliases(host)
41
- addresses = resolve(host.name)
42
- @aliases = addresses.map { |addr| Host.new(addr, host.port, host.tls_name) }
43
- Aerospike.logger.debug("Node Validator found #{aliases.length} addresses for host #{host}: #{@aliases}")
44
- end
41
+ def get_hosts(address)
42
+ aliases = [get_alias(address, host.port)]
43
+
44
+ begin
45
+ conn = Cluster::CreateConnection.(@cluster, Host.new(address, host.port, host.tls_name))
46
+
47
+ commands = %w[node features]
48
+ commands << address_command unless is_loopback?(address)
45
49
 
46
- def set_address(timeout)
47
- @aliases.each do |aliass|
48
- begin
49
- conn = Cluster::CreateConnection.(@cluster, @host)
50
-
51
- info_map = Info.request(conn, 'node', 'build', 'features')
52
- if node_name = info_map['node']
53
- @name = node_name
54
-
55
- # Set features
56
- if features = info_map['features']
57
- @features = features.split(';').to_set
58
- end
59
-
60
- # Check new info protocol support for >= 2.6.6 build
61
- if build_version = info_map['build']
62
- v1, v2, v3 = parse_version_string(build_version)
63
- @use_new_info = v1.to_i > 2 || (v1.to_i == 2 && (v2.to_i > 6 || (v2.to_i == 6 && v3.to_i >= 6)))
64
- end
50
+ info_map = Info.request(conn, *commands)
51
+
52
+ if node_name = info_map['node']
53
+ @name = node_name
54
+
55
+ # Set features
56
+ if features = info_map['features']
57
+ @features = features.split(';').to_set
65
58
  end
66
- ensure
67
- conn.close if conn
68
59
  end
60
+
61
+ unless is_loopback?(address)
62
+ aliases = info_map[address_command].split(',').map { |addr| get_alias(*addr.split(':')) }
63
+ end
64
+ ensure
65
+ conn.close if conn
69
66
  end
67
+
68
+ aliases.map { |al| Host.new(al[:address], al[:port], host.tls_name) }
69
+ end
70
+
71
+ def get_alias(address, port)
72
+ { address: address, port: port }
70
73
  end
71
74
 
72
75
  def resolve(hostname)
@@ -79,16 +82,18 @@ module Aerospike
79
82
  end
80
83
  end
81
84
 
82
- def is_ip?(hostname)
83
- !!((hostname =~ Resolv::IPv4::Regex) || (hostname =~ Resolv::IPv6::Regex))
85
+ def address_command
86
+ @address_command ||= @cluster.tls_enabled? ? 'service-tls-std': 'service-clear-std'
84
87
  end
85
88
 
86
- def parse_version_string(version)
87
- if v = VERSION_REGEXP.match(version)
88
- return v['v1'], v['v2'], v['v3']
89
- end
89
+ def is_loopback?(address)
90
+ info = Addrinfo.ip(address)
91
+ info.ipv4_loopback? || info.ipv6_loopback?
92
+ end
90
93
 
91
- raise Aerospike::Exceptions::Parse.new("Invalid build version string in Info: #{version}")
94
+ def is_ip?(hostname)
95
+ !!((hostname =~ Resolv::IPv4::Regex) || (hostname =~ Resolv::IPv6::Regex))
92
96
  end
97
+
93
98
  end # class
94
- end #module
99
+ 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.
@@ -31,6 +31,7 @@ module Aerospike
31
31
  APPEND = 9
32
32
  PREPEND = 10
33
33
  TOUCH = 11
34
+ DELETE = 14
34
35
 
35
36
  def initialize(op_type, bin_name=nil, bin_value=NullValue.new)
36
37
  @op_type = op_type
@@ -71,6 +72,10 @@ module Aerospike
71
72
  Operation.new(TOUCH)
72
73
  end
73
74
 
75
+ def self.delete
76
+ Operation.new(DELETE)
77
+ end
78
+
74
79
  end
75
80
 
76
81
  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.
@@ -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,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 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,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,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,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-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,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.
@@ -15,6 +15,7 @@
15
15
 
16
16
  require 'aerospike/policy/priority'
17
17
  require 'aerospike/policy/consistency_level'
18
+ require 'aerospike/policy/replica'
18
19
 
19
20
 
20
21
  module Aerospike
@@ -22,7 +23,8 @@ module Aerospike
22
23
  # Container object for client policy command.
23
24
  class Policy
24
25
 
25
- attr_accessor :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level
26
+ attr_accessor :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level,
27
+ :predexp, :fail_on_filtered_out, :replica
26
28
 
27
29
  def initialize(opt={})
28
30
  # Container object for transaction policy attributes used in all database
@@ -32,12 +34,64 @@ module Aerospike
32
34
  # Currently, only used for scans.
33
35
  @priority = opt[:priority] || Priority::DEFAULT
34
36
 
37
+ # Set optional predicate expression filters in postfix notation.
38
+ # Predicate expression filters are applied on the query results on the server.
39
+ # Predicate expression filters may occur on any bin in the record.
40
+ # Requires Aerospike Server versions >= 3.12
41
+ #
42
+ # Postfix notation is described here: http://wiki.c2.com/?PostfixNotation
43
+ #
44
+ # Example:
45
+ #
46
+ # (c >= 11 and c <= 20) or (d > 3 and (d < 5)
47
+ # policy.predexp = [
48
+ # PredExp.integer_bin("c"),
49
+ # PredExp.integer_value(11),
50
+ # PredExp.integer_greater_eq(),
51
+ # PredExp.integer_bin("c"),
52
+ # PredExp.integer_value(20),
53
+ # PredExp.integer_less_eq(),
54
+ # PredExp.and(2),
55
+ # PredExp.integer_bin("d"),
56
+ # PredExp.integer_value(3),
57
+ # PredExp.integer_greater(),
58
+ # PredExp.integer_bin("d"),
59
+ # PredExp.integer_value(5),
60
+ # PredExp.integer_less(),
61
+ # PredExp.and(2),
62
+ # PredExp.or(2)
63
+ # ]
64
+ #
65
+ # # Record last update time > 2017-01-15
66
+ # policy.predexp = [
67
+ # PredExp.rec_last_update(),
68
+ # PredExp.integer_value(Time.new(2017, 1, 15).to_i),
69
+ # PredExp.integer_greater(),
70
+ # PredExp.integer_greater()
71
+ # ]
72
+ @predexp = opt[:predexp] || nil
73
+
74
+
75
+ # Throw exception if @predexp is defined and that filter evaluates
76
+ # to false (transaction ignored). The Aerospike::Exceptions::Aerospike
77
+ # will contain result code Aerospike::ResultCode::FILTERED_OUT.
78
+ # This field is not applicable to batch, scan or query commands.
79
+ @fail_on_filtered_out = opt[:fail_on_filtered_out] || false
80
+
35
81
  # How replicas should be consulted in a read operation to provide the desired
36
82
  # consistency guarantee. Default to allowing one replica to be used in the
37
83
  # read operation.
38
84
  @consistency_level = opt[:consistency_level] || Aerospike::ConsistencyLevel::CONSISTENCY_ONE
39
85
 
40
- # Transaction timeout.
86
+
87
+ # Send read commands to the node containing the key's partition replica type.
88
+ # Write commands are not affected by this setting, because all writes are directed
89
+ # to the node containing the key's master partition.
90
+ #
91
+ # Default to sending read commands to the node containing the key's master partition.
92
+ @replica = opt[:replica] || Aerospike::Replica::MASTER;
93
+
94
+ # Transaction timeout.
41
95
  # This timeout is used to set the socket timeout and is also sent to the
42
96
  # server along with the transaction in the wire protocol.
43
97
  # Default to no timeout (0).
@@ -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,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.
@@ -24,6 +24,7 @@ module Aerospike
24
24
 
25
25
  attr_accessor :include_bin_data
26
26
  attr_accessor :record_queue_size
27
+ attr_accessor :records_per_second
27
28
 
28
29
  def initialize(opt={})
29
30
  super(opt)
@@ -42,6 +43,12 @@ module Aerospike
42
43
  # Default is 5000.
43
44
  @record_queue_size = opt[:record_queue_size] || 5000
44
45
 
46
+ # Limit returned records per second (rps) rate for each server.
47
+ # Will not apply rps limit if records_per_second is zero.
48
+ # Currently only applicable to a query without a defined filter (scan).
49
+ # Default is 0
50
+ @records_per_second = opt[:records_per_second] || 0
51
+
45
52
  self
46
53
  end
47
54
 
@@ -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
  # 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,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.