private void checkSlotsChange(
      ClusterServersConfig cfg, Collection<ClusterPartition> newPartitions) {
    checkSlotsMigration(newPartitions);

    Collection<ClusterSlotRange> newPartitionsSlots = slots(newPartitions);
    Set<ClusterSlotRange> removedSlots = new HashSet<ClusterSlotRange>(lastPartitions.keySet());
    removedSlots.removeAll(newPartitionsSlots);
    lastPartitions.keySet().removeAll(removedSlots);
    if (!removedSlots.isEmpty()) {
      log.info("{} slot ranges found to remove", removedSlots);
    }

    for (ClusterSlotRange slot : removedSlots) {
      MasterSlaveEntry entry = removeMaster(slot);
      entry.removeSlotRange(slot);
      if (entry.getSlotRanges().isEmpty()) {
        entry.shutdownMasterAsync();
        log.info("{} master and slaves for it removed", entry.getClient().getAddr());
      }
    }

    Set<ClusterSlotRange> addedSlots = new HashSet<ClusterSlotRange>(newPartitionsSlots);
    addedSlots.removeAll(lastPartitions.keySet());
    if (!addedSlots.isEmpty()) {
      log.info("{} slots found to add", addedSlots);
    }
    for (final ClusterSlotRange slot : addedSlots) {
      ClusterPartition partition = find(newPartitions, slot);
      boolean masterFound = false;
      for (MasterSlaveEntry entry : getEntries().values()) {
        if (entry.getClient().getAddr().equals(partition.getMasterAddr())) {
          addEntry(slot, entry);
          lastPartitions.put(slot, partition);
          masterFound = true;
          break;
        }
      }
      if (!masterFound) {
        Future<Collection<Future<Void>>> future = addMasterEntry(partition, cfg);
        future.addListener(
            new FutureListener<Collection<Future<Void>>>() {
              @Override
              public void operationComplete(Future<Collection<Future<Void>>> future)
                  throws Exception {
                if (!future.isSuccess()) {
                  log.error(
                      "New cluster slot range " + slot + " without master node detected",
                      future.cause());
                }
              }
            });
      }
    }
  }
  public Future<T> get() {
    for (int j = entries.size() - 1; j >= 0; j--) {
      ClientConnectionsEntry entry = getEntry();
      if (!entry.isFreezed() && tryAcquireConnection(entry)) {
        return connectTo(entry);
      }
    }

    List<InetSocketAddress> zeroConnectionsAmount = new LinkedList<InetSocketAddress>();
    List<InetSocketAddress> freezed = new LinkedList<InetSocketAddress>();
    for (ClientConnectionsEntry entry : entries) {
      if (entry.isFreezed()) {
        freezed.add(entry.getClient().getAddr());
      } else {
        zeroConnectionsAmount.add(entry.getClient().getAddr());
      }
    }

    StringBuilder errorMsg;
    if (connectionManager.isClusterMode()) {
      errorMsg =
          new StringBuilder(
              "Connection pool exhausted! for slots: " + masterSlaveEntry.getSlotRanges());
    } else {
      errorMsg = new StringBuilder("Connection pool exhausted! ");
    }
    if (!freezed.isEmpty()) {
      errorMsg.append(" Disconnected hosts: " + freezed);
    }
    if (!zeroConnectionsAmount.isEmpty()) {
      errorMsg.append(" Hosts with fully busy connections: " + zeroConnectionsAmount);
    }

    RedisConnectionException exception = new RedisConnectionException(errorMsg.toString());
    return connectionManager.newFailedFuture(exception);
  }