/**
   * Update token map with a set of token/endpoint pairs in normal state.
   *
   * <p>Prefer this whenever there are multiple pairs to update, as each update (whether a single or
   * multiple) is expensive (CASSANDRA-3831).
   *
   * @param endpointTokens
   */
  public void updateNormalTokens(Multimap<InetAddress, Token> endpointTokens) {
    if (endpointTokens.isEmpty()) return;

    lock.writeLock().lock();
    try {
      boolean shouldSortTokens = false;
      for (InetAddress endpoint : endpointTokens.keySet()) {
        Collection<Token> tokens = endpointTokens.get(endpoint);

        assert tokens != null && !tokens.isEmpty();

        bootstrapTokens.removeValue(endpoint);
        tokenToEndpointMap.removeValue(endpoint);
        topology.addEndpoint(endpoint);
        leavingEndpoints.remove(endpoint);
        removeFromMoving(endpoint); // also removing this endpoint from moving

        for (Token token : tokens) {
          InetAddress prev = tokenToEndpointMap.put(token, endpoint);
          if (!endpoint.equals(prev)) {
            if (prev != null)
              logger.warn("Token {} changing ownership from {} to {}", token, prev, endpoint);
            shouldSortTokens = true;
          }
        }
      }

      if (shouldSortTokens) sortedTokens = sortTokens();
    } finally {
      lock.writeLock().unlock();
    }
  }
 /** used by tests */
 public void clearUnsafe() {
   lock.writeLock().lock();
   try {
     bootstrapTokens.clear();
     tokenToEndpointMap.clear();
     topology.clear();
     leavingEndpoints.clear();
     pendingRanges.clear();
     endpointToHostIdMap.clear();
     invalidateCachedRings();
   } finally {
     lock.writeLock().unlock();
   }
 }
  public void removeEndpoint(InetAddress endpoint) {
    assert endpoint != null;

    lock.writeLock().lock();
    try {
      bootstrapTokens.removeValue(endpoint);
      tokenToEndpointMap.removeValue(endpoint);
      topology.removeEndpoint(endpoint);
      leavingEndpoints.remove(endpoint);
      endpointToHostIdMap.remove(endpoint);
      sortedTokens = sortTokens();
      invalidateCachedRings();
    } finally {
      lock.writeLock().unlock();
    }
  }