public Result compute()

in core/src/main/java/com/datastax/oss/driver/internal/core/metadata/FullNodeListRefresh.java [50:125]


  public Result compute(
      DefaultMetadata oldMetadata, boolean tokenMapEnabled, InternalDriverContext context) {

    String logPrefix = context.getSessionName();
    TokenFactoryRegistry tokenFactoryRegistry = context.getTokenFactoryRegistry();

    Map<UUID, Node> oldNodes = oldMetadata.getNodes();

    Map<UUID, Node> added = new HashMap<>();
    Set<UUID> seen = new HashSet<>();

    TokenFactory tokenFactory =
        oldMetadata.getTokenMap().map(m -> ((DefaultTokenMap) m).getTokenFactory()).orElse(null);
    boolean tokensChanged = false;

    for (NodeInfo nodeInfo : nodeInfos) {
      UUID id = nodeInfo.getHostId();
      if (seen.contains(id)) {
        LOG.warn(
            "[{}] Found duplicate entries with host_id {} in system.peers, "
                + "keeping only the first one",
            logPrefix,
            id);
      } else {
        seen.add(id);
        DefaultNode node = (DefaultNode) oldNodes.get(id);
        if (node == null) {
          node = new DefaultNode(nodeInfo.getEndPoint(), context);
          LOG.debug("[{}] Adding new node {}", logPrefix, node);
          added.put(id, node);
        }
        if (tokenFactory == null && nodeInfo.getPartitioner() != null) {
          tokenFactory = tokenFactoryRegistry.tokenFactoryFor(nodeInfo.getPartitioner());
        }
        tokensChanged |= copyInfos(nodeInfo, node, context);
      }
    }

    Set<UUID> removed = Sets.difference(oldNodes.keySet(), seen);

    if (added.isEmpty() && removed.isEmpty()) { // The list didn't change
      if (!oldMetadata.getTokenMap().isPresent() && tokenFactory != null) {
        // First time we found out what the partitioner is => set the token factory and trigger a
        // token map rebuild:
        return new Result(
            oldMetadata.withNodes(
                oldMetadata.getNodes(), tokenMapEnabled, true, tokenFactory, context));
      } else {
        // No need to create a new metadata instance
        return new Result(oldMetadata);
      }
    } else {
      ImmutableMap.Builder<UUID, Node> newNodesBuilder = ImmutableMap.builder();
      ImmutableList.Builder<Object> eventsBuilder = ImmutableList.builder();

      newNodesBuilder.putAll(added);
      for (Map.Entry<UUID, Node> entry : oldNodes.entrySet()) {
        if (!removed.contains(entry.getKey())) {
          newNodesBuilder.put(entry.getKey(), entry.getValue());
        }
      }

      for (Node node : added.values()) {
        eventsBuilder.add(NodeStateEvent.added((DefaultNode) node));
      }
      for (UUID id : removed) {
        Node node = oldNodes.get(id);
        eventsBuilder.add(NodeStateEvent.removed((DefaultNode) node));
      }

      return new Result(
          oldMetadata.withNodes(
              newNodesBuilder.build(), tokenMapEnabled, tokensChanged, tokenFactory, context),
          eventsBuilder.build());
    }
  }