diff --git a/locator/token_metadata.cc b/locator/token_metadata.cc index 24e447f4b9..b481aa8e0d 100644 --- a/locator/token_metadata.cc +++ b/locator/token_metadata.cc @@ -188,4 +188,45 @@ bool token_metadata::is_member(inet_address endpoint) { }); } +void token_metadata::add_bootstrap_token(token t, inet_address endpoint) { + std::unordered_set tokens{t}; + add_bootstrap_tokens(tokens, endpoint); +} + +void token_metadata::add_bootstrap_tokens(std::unordered_set tokens, inet_address endpoint) { + for (auto t : tokens) { + auto old_endpoint = _bootstrap_tokens.find(t); + if (old_endpoint != _bootstrap_tokens.end() && (*old_endpoint).second != endpoint) { + auto msg = sprint("Bootstrap Token collision between %s and %s (token %s", (*old_endpoint).second, endpoint, t); + throw std::runtime_error(msg); + } + + auto old_endpoint2 = _token_to_endpoint_map.find(t); + if (old_endpoint2 != _token_to_endpoint_map.end() && (*old_endpoint2).second != endpoint) { + auto msg = sprint("Bootstrap Token collision between %s and %s (token %s", (*old_endpoint2).second, endpoint, t); + throw std::runtime_error(msg); + } + } + + // Unfortunately, std::remove_if does not work with std::map + for (auto it = _bootstrap_tokens.begin(); it != _bootstrap_tokens.end();) { + if ((*it).second == endpoint) { + it = _bootstrap_tokens.erase(it); + } else { + it++; + } + } + + for (auto t : tokens) { + _bootstrap_tokens[t] = endpoint; + } +} + +void token_metadata::remove_bootstrap_tokens(std::unordered_set tokens) { + assert(!tokens.empty()); + for (auto t : tokens) { + _bootstrap_tokens.erase(t); + } +} + } diff --git a/locator/token_metadata.hh b/locator/token_metadata.hh index 786753a30a..71a5e1af40 100644 --- a/locator/token_metadata.hh +++ b/locator/token_metadata.hh @@ -53,6 +53,8 @@ private: /** Maintains endpoint to host ID map of every node in the cluster */ std::unordered_map _endpoint_to_host_id_map; + std::unordered_map _bootstrap_tokens; + std::vector _sorted_tokens; topology _topology; @@ -165,7 +167,7 @@ public: lock.readLock().lock(); try { - for (Token token : bootstrapTokens.keySet()) + for (Token token : _bootstrap_tokens.keySet()) for (Range range : sourceRanges) if (range.contains(token)) n++; @@ -216,7 +218,7 @@ public: assert tokens != null && !tokens.isEmpty(); - bootstrapTokens.removeValue(endpoint); + _bootstrap_tokens.removeValue(endpoint); tokenToEndpointMap.removeValue(endpoint); topology.addEndpoint(endpoint); leavingEndpoints.remove(endpoint); @@ -262,63 +264,13 @@ public: /** @return a copy of the endpoint-to-id map for read-only operations */ const auto& get_endpoint_to_host_id_map_for_reading(); + void add_bootstrap_token(token t, inet_address endpoint); + + void add_bootstrap_tokens(std::unordered_set tokens, inet_address endpoint); + + void remove_bootstrap_tokens(std::unordered_set tokens); #if 0 - @Deprecated - public void addBootstrapToken(Token token, InetAddress endpoint) - { - addBootstrapTokens(Collections.singleton(token), endpoint); - } - - public void addBootstrapTokens(Collection tokens, InetAddress endpoint) - { - assert tokens != null && !tokens.isEmpty(); - assert endpoint != null; - - lock.writeLock().lock(); - try - { - - InetAddress oldEndpoint; - - for (Token token : tokens) - { - oldEndpoint = bootstrapTokens.get(token); - if (oldEndpoint != null && !oldEndpoint.equals(endpoint)) - throw new RuntimeException("Bootstrap Token collision between " + oldEndpoint + " and " + endpoint + " (token " + token); - - oldEndpoint = tokenToEndpointMap.get(token); - if (oldEndpoint != null && !oldEndpoint.equals(endpoint)) - throw new RuntimeException("Bootstrap Token collision between " + oldEndpoint + " and " + endpoint + " (token " + token); - } - - bootstrapTokens.removeValue(endpoint); - - for (Token token : tokens) - bootstrapTokens.put(token, endpoint); - } - finally - { - lock.writeLock().unlock(); - } - } - - public void removeBootstrapTokens(Collection tokens) - { - assert tokens != null && !tokens.isEmpty(); - - lock.writeLock().lock(); - try - { - for (Token token : tokens) - bootstrapTokens.remove(token); - } - finally - { - lock.writeLock().unlock(); - } - } - public void addLeavingEndpoint(InetAddress endpoint) { assert endpoint != null; @@ -362,7 +314,7 @@ public: lock.writeLock().lock(); try { - bootstrapTokens.removeValue(endpoint); + _bootstrap_tokens.removeValue(endpoint); tokenToEndpointMap.removeValue(endpoint); topology.removeEndpoint(endpoint); leavingEndpoints.remove(endpoint); @@ -661,7 +613,7 @@ public: { Multimap, InetAddress> newPendingRanges = HashMultimap.create(); - if (bootstrapTokens.isEmpty() && leavingEndpoints.isEmpty() && movingEndpoints.isEmpty()) + if (_bootstrap_tokens.isEmpty() && leavingEndpoints.isEmpty() && movingEndpoints.isEmpty()) { if (logger.isDebugEnabled()) logger.debug("No bootstrapping, leaving or moving nodes -> empty pending ranges for {}", keyspaceName); @@ -695,7 +647,7 @@ public: // For each of the bootstrapping nodes, simply add and remove them one by one to // allLeftMetadata and check in between what their ranges would be. - Multimap bootstrapAddresses = bootstrapTokens.inverse(); + Multimap bootstrapAddresses = _bootstrap_tokens.inverse(); for (InetAddress endpoint : bootstrapAddresses.keySet()) { Collection tokens = bootstrapAddresses.get(endpoint); @@ -759,7 +711,7 @@ public: lock.readLock().lock(); try { - return new BiMultiValMap(bootstrapTokens); + return new BiMultiValMap(_bootstrap_tokens); } finally { @@ -879,7 +831,7 @@ public: { tokenToEndpointMap.clear(); _endpoint_to_host_id_map.clear(); - bootstrapTokens.clear(); + _bootstrap_tokens.clear(); leavingEndpoints.clear(); pendingRanges.clear(); movingEndpoints.clear(); @@ -914,11 +866,11 @@ public: } } - if (!bootstrapTokens.isEmpty()) + if (!_bootstrap_tokens.isEmpty()) { sb.append("Bootstrapping Tokens:" ); sb.append(System.getProperty("line.separator")); - for (Map.Entry entry : bootstrapTokens.entrySet()) + for (Map.Entry entry : _bootstrap_tokens.entrySet()) { sb.append(entry.getValue()).append(":").append(entry.getKey()); sb.append(System.getProperty("line.separator")); @@ -1017,9 +969,9 @@ public: lock.readLock().lock(); try { - Map map = new HashMap(tokenToEndpointMap.size() + bootstrapTokens.size()); + Map map = new HashMap(tokenToEndpointMap.size() + _bootstrap_tokens.size()); map.putAll(tokenToEndpointMap); - map.putAll(bootstrapTokens); + map.putAll(_bootstrap_tokens); return map; } finally