cassandra-driver 1.0.0.beta.2-java
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.
- checksums.yaml +7 -0
- data/.yardopts +4 -0
- data/README.md +125 -0
- data/lib/cassandra/auth/providers/password.rb +73 -0
- data/lib/cassandra/auth/providers.rb +16 -0
- data/lib/cassandra/auth.rb +97 -0
- data/lib/cassandra/client/batch.rb +212 -0
- data/lib/cassandra/client/client.rb +591 -0
- data/lib/cassandra/client/column_metadata.rb +54 -0
- data/lib/cassandra/client/connection_manager.rb +72 -0
- data/lib/cassandra/client/connector.rb +277 -0
- data/lib/cassandra/client/execute_options_decoder.rb +59 -0
- data/lib/cassandra/client/null_logger.rb +37 -0
- data/lib/cassandra/client/peer_discovery.rb +50 -0
- data/lib/cassandra/client/prepared_statement.rb +314 -0
- data/lib/cassandra/client/query_result.rb +230 -0
- data/lib/cassandra/client/request_runner.rb +71 -0
- data/lib/cassandra/client/result_metadata.rb +48 -0
- data/lib/cassandra/client/void_result.rb +78 -0
- data/lib/cassandra/client.rb +144 -0
- data/lib/cassandra/cluster/client.rb +768 -0
- data/lib/cassandra/cluster/connector.rb +244 -0
- data/lib/cassandra/cluster/control_connection.rb +425 -0
- data/lib/cassandra/cluster/metadata.rb +124 -0
- data/lib/cassandra/cluster/options.rb +42 -0
- data/lib/cassandra/cluster/registry.rb +198 -0
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +47 -0
- data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
- data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
- data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +92 -0
- data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
- data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
- data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
- data/lib/cassandra/cluster/schema/type_parser.rb +138 -0
- data/lib/cassandra/cluster/schema.rb +340 -0
- data/lib/cassandra/cluster.rb +215 -0
- data/lib/cassandra/column.rb +92 -0
- data/lib/cassandra/compression/compressors/lz4.rb +72 -0
- data/lib/cassandra/compression/compressors/snappy.rb +66 -0
- data/lib/cassandra/compression.rb +66 -0
- data/lib/cassandra/driver.rb +111 -0
- data/lib/cassandra/errors.rb +79 -0
- data/lib/cassandra/execution/info.rb +51 -0
- data/lib/cassandra/execution/options.rb +80 -0
- data/lib/cassandra/execution/trace.rb +152 -0
- data/lib/cassandra/future.rb +675 -0
- data/lib/cassandra/host.rb +79 -0
- data/lib/cassandra/keyspace.rb +133 -0
- data/lib/cassandra/listener.rb +87 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +149 -0
- data/lib/cassandra/load_balancing/policies/round_robin.rb +132 -0
- data/lib/cassandra/load_balancing/policies/token_aware.rb +119 -0
- data/lib/cassandra/load_balancing/policies/white_list.rb +90 -0
- data/lib/cassandra/load_balancing/policies.rb +19 -0
- data/lib/cassandra/load_balancing.rb +113 -0
- data/lib/cassandra/protocol/cql_byte_buffer.rb +307 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +323 -0
- data/lib/cassandra/protocol/frame_decoder.rb +128 -0
- data/lib/cassandra/protocol/frame_encoder.rb +48 -0
- data/lib/cassandra/protocol/request.rb +38 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +47 -0
- data/lib/cassandra/protocol/requests/batch_request.rb +76 -0
- data/lib/cassandra/protocol/requests/credentials_request.rb +47 -0
- data/lib/cassandra/protocol/requests/execute_request.rb +103 -0
- data/lib/cassandra/protocol/requests/options_request.rb +39 -0
- data/lib/cassandra/protocol/requests/prepare_request.rb +50 -0
- data/lib/cassandra/protocol/requests/query_request.rb +153 -0
- data/lib/cassandra/protocol/requests/register_request.rb +38 -0
- data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
- data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
- data/lib/cassandra/protocol/response.rb +38 -0
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +41 -0
- data/lib/cassandra/protocol/responses/auth_success_response.rb +41 -0
- data/lib/cassandra/protocol/responses/authenticate_response.rb +41 -0
- data/lib/cassandra/protocol/responses/detailed_error_response.rb +60 -0
- data/lib/cassandra/protocol/responses/error_response.rb +50 -0
- data/lib/cassandra/protocol/responses/event_response.rb +39 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +64 -0
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +43 -0
- data/lib/cassandra/protocol/responses/ready_response.rb +44 -0
- data/lib/cassandra/protocol/responses/result_response.rb +48 -0
- data/lib/cassandra/protocol/responses/rows_result_response.rb +139 -0
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +60 -0
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +57 -0
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +42 -0
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +44 -0
- data/lib/cassandra/protocol/responses/supported_response.rb +41 -0
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +34 -0
- data/lib/cassandra/protocol/responses/void_result_response.rb +39 -0
- data/lib/cassandra/protocol/type_converter.rb +384 -0
- data/lib/cassandra/protocol.rb +93 -0
- data/lib/cassandra/reconnection/policies/constant.rb +48 -0
- data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
- data/lib/cassandra/reconnection/policies.rb +20 -0
- data/lib/cassandra/reconnection.rb +49 -0
- data/lib/cassandra/result.rb +215 -0
- data/lib/cassandra/retry/policies/default.rb +47 -0
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +71 -0
- data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
- data/lib/cassandra/retry/policies.rb +21 -0
- data/lib/cassandra/retry.rb +142 -0
- data/lib/cassandra/session.rb +202 -0
- data/lib/cassandra/statement.rb +22 -0
- data/lib/cassandra/statements/batch.rb +95 -0
- data/lib/cassandra/statements/bound.rb +48 -0
- data/lib/cassandra/statements/prepared.rb +81 -0
- data/lib/cassandra/statements/simple.rb +58 -0
- data/lib/cassandra/statements/void.rb +33 -0
- data/lib/cassandra/statements.rb +23 -0
- data/lib/cassandra/table.rb +299 -0
- data/lib/cassandra/time_uuid.rb +142 -0
- data/lib/cassandra/util.rb +167 -0
- data/lib/cassandra/uuid.rb +104 -0
- data/lib/cassandra/version.rb +21 -0
- data/lib/cassandra.rb +428 -0
- data/lib/cassandra_murmur3.jar +0 -0
- metadata +211 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Metadata
|
|
23
|
+
include MonitorMixin
|
|
24
|
+
|
|
25
|
+
attr_reader :name
|
|
26
|
+
|
|
27
|
+
def initialize(cluster_registry, cluster_schema, schema_partitioners, replication_strategies, default_replication_strategy)
|
|
28
|
+
@registry = cluster_registry
|
|
29
|
+
@schema = cluster_schema
|
|
30
|
+
@partitioners = schema_partitioners
|
|
31
|
+
@strategies = replication_strategies
|
|
32
|
+
@default_strategy = default_replication_strategy
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def find_replicas(keyspace, statement)
|
|
36
|
+
unless statement.respond_to?(:partition_key) && statement.respond_to?(:keyspace)
|
|
37
|
+
return EMPTY_LIST
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
keyspace = String(statement.keyspace || keyspace)
|
|
41
|
+
partition_key = statement.partition_key
|
|
42
|
+
return EMPTY_LIST unless keyspace && partition_key
|
|
43
|
+
|
|
44
|
+
partitioner = @partitioner
|
|
45
|
+
return EMPTY_LIST unless partitioner
|
|
46
|
+
|
|
47
|
+
keyspace_hosts = @token_replicas[keyspace]
|
|
48
|
+
return EMPTY_LIST if keyspace_hosts.nil? || keyspace_hosts.empty?
|
|
49
|
+
|
|
50
|
+
token = partitioner.create_token(partition_key)
|
|
51
|
+
index = insertion_point(@token_ring, token)
|
|
52
|
+
index = 0 if index >= @token_ring.size
|
|
53
|
+
hosts = keyspace_hosts[@token_ring[index]]
|
|
54
|
+
return EMPTY_LIST unless hosts
|
|
55
|
+
|
|
56
|
+
hosts
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def update(data)
|
|
60
|
+
@name = data['name']
|
|
61
|
+
@partitioner = @partitioners[data['partitioner']]
|
|
62
|
+
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def rebuild_token_map
|
|
67
|
+
partitioner = @partitioner
|
|
68
|
+
return self unless partitioner
|
|
69
|
+
|
|
70
|
+
tokens = ::SortedSet.new
|
|
71
|
+
token_to_host = ::Hash.new
|
|
72
|
+
|
|
73
|
+
@registry.each_host do |host|
|
|
74
|
+
host.tokens.each do |token|
|
|
75
|
+
token = partitioner.parse_token(token) rescue next
|
|
76
|
+
tokens.add(token)
|
|
77
|
+
token_to_host[token] = host
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
token_ring = tokens.to_a
|
|
82
|
+
token_replicas = ::Hash.new
|
|
83
|
+
|
|
84
|
+
@schema.each_keyspace do |keyspace|
|
|
85
|
+
replication = keyspace.replication
|
|
86
|
+
strategy = @strategies[replication.klass] || @default_strategy
|
|
87
|
+
|
|
88
|
+
token_replicas[keyspace.name] = strategy.replication_map(
|
|
89
|
+
token_to_host,
|
|
90
|
+
token_ring,
|
|
91
|
+
replication.options
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
@token_replicas = token_replicas
|
|
96
|
+
@token_ring = token_ring
|
|
97
|
+
|
|
98
|
+
self
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def insertion_point(list, item)
|
|
104
|
+
min = 0
|
|
105
|
+
max = list.size - 1
|
|
106
|
+
|
|
107
|
+
while min <= max do
|
|
108
|
+
idx = (min + max) / 2
|
|
109
|
+
val = list[idx]
|
|
110
|
+
|
|
111
|
+
if val < item
|
|
112
|
+
min = idx + 1
|
|
113
|
+
elsif val > item
|
|
114
|
+
max = idx - 1
|
|
115
|
+
else
|
|
116
|
+
return idx # item found
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
min # item not found.
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Options
|
|
23
|
+
attr_reader :credentials, :auth_provider, :compressor, :port,
|
|
24
|
+
:connect_timeout, :ssl, :connections_per_local_node,
|
|
25
|
+
:connections_per_remote_node
|
|
26
|
+
attr_accessor :protocol_version
|
|
27
|
+
|
|
28
|
+
def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node)
|
|
29
|
+
@protocol_version = protocol_version
|
|
30
|
+
@credentials = credentials
|
|
31
|
+
@auth_provider = auth_provider
|
|
32
|
+
@compressor = compressor
|
|
33
|
+
@port = port
|
|
34
|
+
@connect_timeout = connect_timeout
|
|
35
|
+
@ssl = ssl
|
|
36
|
+
|
|
37
|
+
@connections_per_local_node = connections_per_local_node
|
|
38
|
+
@connections_per_remote_node = connections_per_remote_node
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Registry
|
|
23
|
+
include MonitorMixin
|
|
24
|
+
|
|
25
|
+
LISTENER_METHODS = [:host_found, :host_lost, :host_up, :host_down].freeze
|
|
26
|
+
|
|
27
|
+
def initialize(logger)
|
|
28
|
+
@logger = logger
|
|
29
|
+
@hosts = ::Hash.new
|
|
30
|
+
@listeners = ::Set.new
|
|
31
|
+
|
|
32
|
+
mon_initialize
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_listener(listener)
|
|
36
|
+
synchronize { @listeners = @listeners.dup.add(listener) }
|
|
37
|
+
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def remove_listener(listener)
|
|
42
|
+
synchronize { @listeners = @listeners.dup.delete(listener) }
|
|
43
|
+
|
|
44
|
+
self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def each_host(&block)
|
|
48
|
+
if block_given?
|
|
49
|
+
@hosts.each_value(&block)
|
|
50
|
+
self
|
|
51
|
+
else
|
|
52
|
+
@hosts.values
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
alias :hosts :each_host
|
|
56
|
+
|
|
57
|
+
def host(address)
|
|
58
|
+
@hosts[address.to_s]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def has_host?(address)
|
|
62
|
+
@hosts.has_key?(address.to_s)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def host_found(address, data = {})
|
|
66
|
+
ip = address.to_s
|
|
67
|
+
host = @hosts[ip]
|
|
68
|
+
|
|
69
|
+
if host
|
|
70
|
+
if host.id == data['host_id'] &&
|
|
71
|
+
host.release_version == data['release_version'] &&
|
|
72
|
+
host.rack == data['rack'] &&
|
|
73
|
+
host.datacenter == data['data_center']
|
|
74
|
+
|
|
75
|
+
return self
|
|
76
|
+
else
|
|
77
|
+
notify_lost(host)
|
|
78
|
+
|
|
79
|
+
host = create_host(address, data)
|
|
80
|
+
|
|
81
|
+
notify_found(host)
|
|
82
|
+
end
|
|
83
|
+
else
|
|
84
|
+
host = create_host(address, data)
|
|
85
|
+
|
|
86
|
+
notify_found(host)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
synchronize do
|
|
90
|
+
hosts = @hosts.dup
|
|
91
|
+
hosts[ip] = host
|
|
92
|
+
@hosts = hosts
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
self
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def host_down(address)
|
|
99
|
+
ip = address.to_s
|
|
100
|
+
host = @hosts[ip]
|
|
101
|
+
|
|
102
|
+
return self unless host && !host.down?
|
|
103
|
+
|
|
104
|
+
host = toggle_down(host)
|
|
105
|
+
|
|
106
|
+
synchronize do
|
|
107
|
+
hosts = @hosts.dup
|
|
108
|
+
hosts[ip] = host
|
|
109
|
+
@hosts = hosts
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
self
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def host_up(address)
|
|
116
|
+
ip = address.to_s
|
|
117
|
+
host = @hosts[ip]
|
|
118
|
+
|
|
119
|
+
return self unless host && !host.up?
|
|
120
|
+
|
|
121
|
+
host = toggle_up(host)
|
|
122
|
+
|
|
123
|
+
synchronize do
|
|
124
|
+
hosts = @hosts.dup
|
|
125
|
+
hosts[ip] = host
|
|
126
|
+
@hosts = hosts
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
self
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def host_lost(address)
|
|
133
|
+
ip = address.to_s
|
|
134
|
+
host = nil
|
|
135
|
+
|
|
136
|
+
return self unless @hosts.has_key?(ip)
|
|
137
|
+
|
|
138
|
+
synchronize do
|
|
139
|
+
hosts = @hosts.dup
|
|
140
|
+
host = hosts.delete(ip)
|
|
141
|
+
@hosts = hosts
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
notify_lost(host)
|
|
145
|
+
|
|
146
|
+
host
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def create_host(ip, data)
|
|
152
|
+
Host.new(ip, data['host_id'], data['rack'], data['data_center'], data['release_version'], data['tokens'].freeze, :up)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def toggle_up(host)
|
|
156
|
+
host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :up)
|
|
157
|
+
@logger.debug("Host #{host.ip} is up")
|
|
158
|
+
@listeners.each do |listener|
|
|
159
|
+
listener.host_up(host) rescue nil
|
|
160
|
+
end
|
|
161
|
+
host
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def toggle_down(host)
|
|
165
|
+
host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
|
|
166
|
+
@logger.debug("Host #{host.ip} is down")
|
|
167
|
+
@listeners.each do |listener|
|
|
168
|
+
listener.host_down(host) rescue nil
|
|
169
|
+
end
|
|
170
|
+
host
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def notify_lost(host)
|
|
174
|
+
if host.up?
|
|
175
|
+
@logger.debug("Host #{host.ip} is down and lost")
|
|
176
|
+
host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
|
|
177
|
+
@listeners.each do |listener|
|
|
178
|
+
listener.host_down(host) rescue nil
|
|
179
|
+
listener.host_lost(host) rescue nil
|
|
180
|
+
end
|
|
181
|
+
else
|
|
182
|
+
@logger.debug("Host #{host.ip} is lost")
|
|
183
|
+
@listeners.each do |listener|
|
|
184
|
+
listener.host_lost(host) rescue nil
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def notify_found(host)
|
|
190
|
+
@logger.debug("Host #{host.ip} is found and up")
|
|
191
|
+
@listeners.each do |listener|
|
|
192
|
+
listener.host_found(host) rescue nil
|
|
193
|
+
listener.host_up(host) rescue nil
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module Partitioners
|
|
24
|
+
# @private
|
|
25
|
+
class Murmur3
|
|
26
|
+
def create_token(partition_key)
|
|
27
|
+
token = Cassandra::Murmur3.hash(partition_key)
|
|
28
|
+
token = LONG_MAX if token == LONG_MIN
|
|
29
|
+
|
|
30
|
+
token
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def parse_token(token_string)
|
|
34
|
+
token_string.to_i
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# @private
|
|
40
|
+
LONG_MIN = -2 ** 63
|
|
41
|
+
# @private
|
|
42
|
+
LONG_MAX = 2 ** 63 - 1
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module Partitioners
|
|
24
|
+
# @private
|
|
25
|
+
class Ordered
|
|
26
|
+
def create_token(partition_key)
|
|
27
|
+
partition_key
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse_token(token_string)
|
|
31
|
+
token_string
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module Partitioners
|
|
24
|
+
# @private
|
|
25
|
+
class Random
|
|
26
|
+
def create_token(partition_key)
|
|
27
|
+
Digest::MD5.hexdigest(partition_key).to_i(16)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse_token(token_string)
|
|
31
|
+
token_string.to_i
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
require 'cassandra/cluster/schema/partitioners/ordered'
|
|
20
|
+
require 'cassandra/cluster/schema/partitioners/random'
|
|
21
|
+
require 'cassandra/cluster/schema/partitioners/murmur3'
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module ReplicationStrategies
|
|
24
|
+
# @private
|
|
25
|
+
class NetworkTopology
|
|
26
|
+
def replication_map(token_hosts, token_ring, replication_options)
|
|
27
|
+
size = token_ring.size
|
|
28
|
+
racks = ::Hash.new
|
|
29
|
+
token_hosts.each_value do |host|
|
|
30
|
+
racks[host.datacenter] ||= ::Set.new
|
|
31
|
+
racks[host.datacenter].add(host.rack)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
replication_map = ::Hash.new
|
|
35
|
+
|
|
36
|
+
token_ring.each_with_index do |token, i|
|
|
37
|
+
all_replicas = ::Hash.new
|
|
38
|
+
visited = ::Hash.new
|
|
39
|
+
skipped_datacenter_hosts = ::Hash.new
|
|
40
|
+
replicas = ::Set.new
|
|
41
|
+
|
|
42
|
+
size.times do |j|
|
|
43
|
+
break if all_replicas.size == racks.size && !all_replicas.any? {|(datacenter, r)| r.size < Integer(replication_options[datacenter])}
|
|
44
|
+
|
|
45
|
+
host = token_hosts[token_ring[(i + j) % size]]
|
|
46
|
+
datacenter = host.datacenter
|
|
47
|
+
next if datacenter.nil?
|
|
48
|
+
|
|
49
|
+
factor = replication_options[datacenter]
|
|
50
|
+
next unless factor
|
|
51
|
+
|
|
52
|
+
factor = Integer(factor) rescue next
|
|
53
|
+
|
|
54
|
+
replicas_in_datacenter = all_replicas[datacenter] ||= ::Set.new
|
|
55
|
+
next if replicas_in_datacenter.size >= factor
|
|
56
|
+
|
|
57
|
+
rack = host.rack
|
|
58
|
+
visited_racks = visited[datacenter] ||= ::Set.new
|
|
59
|
+
|
|
60
|
+
if rack.nil? || visited_racks.size == racks[datacenter].size
|
|
61
|
+
replicas << host
|
|
62
|
+
replicas_in_datacenter << host
|
|
63
|
+
else
|
|
64
|
+
if visited_racks.include?(rack)
|
|
65
|
+
skipped_hosts = skipped_datacenter_hosts[datacenter] ||= ::Set.new
|
|
66
|
+
skipped_hosts << host
|
|
67
|
+
else
|
|
68
|
+
replicas << host
|
|
69
|
+
replicas_in_datacenter << host
|
|
70
|
+
visited_racks << rack
|
|
71
|
+
|
|
72
|
+
if visited_racks.size == racks[datacenter].size && (skipped_hosts = skipped_datacenter_hosts[datacenter]) && replicas_in_datacenter.size < factor
|
|
73
|
+
skipped_hosts.each do |skipped_host|
|
|
74
|
+
replicas << skipped_host
|
|
75
|
+
replicas_in_datacenter << skipped_host
|
|
76
|
+
break if replicas_in_datacenter.size >= factor
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
replication_map[token] = replicas.to_a.freeze
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
replication_map
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module ReplicationStrategies
|
|
24
|
+
# @private
|
|
25
|
+
class None
|
|
26
|
+
def replication_map(token_hosts, token_ring, replication_options)
|
|
27
|
+
replication_map = ::Hash.new
|
|
28
|
+
|
|
29
|
+
token_hosts.each do |token, host|
|
|
30
|
+
replication_map[token] = [host].freeze
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
replication_map
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#++
|
|
18
|
+
|
|
19
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
class Schema
|
|
22
|
+
# @private
|
|
23
|
+
module ReplicationStrategies
|
|
24
|
+
# @private
|
|
25
|
+
class Simple
|
|
26
|
+
def replication_map(token_hosts, token_ring, replication_options)
|
|
27
|
+
factor = Integer(replication_options['replication_factor'])
|
|
28
|
+
size = token_ring.size
|
|
29
|
+
factor = size if size < factor
|
|
30
|
+
replication_map = ::Hash.new
|
|
31
|
+
|
|
32
|
+
token_ring.each_with_index do |token, i|
|
|
33
|
+
replication_map[token] = factor.times.map do |j|
|
|
34
|
+
token_hosts[token_ring[(i + j) % size]]
|
|
35
|
+
end.freeze
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
replication_map
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|