/** * Deregisters the given {@code member} and returns a new {@link ConsistentHash} with updated memberships. * * @param member the member to remove from the consistent hash * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash without(Member member) { Assert.notNull(member, () -> "Member may not be null"); if (!members.containsKey(member.name())) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.remove(member.name()); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
/** * Registers the given {@code member} with given {@code loadFactor} and {@code commandFilter} if it is not * already contained in the {@link ConsistentHash}. It will return the current ConsistentHash if the addition is * a duplicate and returns a new ConsistentHash with updated memberships if it is not. * <p> * The relative loadFactor of the member determines the likelihood of being selected as a destination for a command. * * @param member the member to register * @param loadFactor the load factor of the new member * @param commandFilter filter describing which commands can be handled by the given member * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash with(Member member, int loadFactor, CommandMessageFilter commandFilter) { Assert.notNull(member, () -> "Member may not be null"); ConsistentHashMember newMember = new ConsistentHashMember(member, loadFactor, commandFilter); if (members.containsKey(member.name()) && newMember.equals(members.get(member.name()))) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.put(member.name(), newMember); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
/** * Returns a ConsistentHash instance where only segments leading to the given <code>nodes</code> are available. * Each * lookup will always result in one of the given <code>nodes</code>. * * @param nodes The nodes to keep in the consistent hash * @return a ConsistentHash instance where only segments leading to the given <code>nodes</code> are available */ public ConsistentHash withExclusively(Collection<String> nodes) { Set<String> activeMembers = new HashSet<String>(nodes); SortedMap<String, Member> newHashes = new TreeMap<String, Member>(); for (Map.Entry<String, Member> entry : hashToMember.entrySet()) { if (activeMembers.contains(entry.getValue().name())) { newHashes.put(entry.getKey(), entry.getValue()); } } return new ConsistentHash(newHashes); }
private void updateMemberships() { AtomicReference<ConsistentHash> updatedConsistentHash = new AtomicReference<>(new ConsistentHash()); List<ServiceInstance> instances = discoveryClient.getServices().stream() .map(discoveryClient::getInstances) .flatMap(Collection::stream) .filter(serviceInstanceFilter) .collect(Collectors.toList()); cleanBlackList(instances); instances.stream() .filter(this::ifNotBlackListed) .forEach(serviceInstance -> updateMembershipForServiceInstance(serviceInstance, updatedConsistentHash)); ConsistentHash newConsistentHash = updatedConsistentHash.get(); atomicConsistentHash.set(newConsistentHash); consistentHashChangeListener.onConsistentHashChanged(newConsistentHash); }
/** * Deregisters the given {@code member} and returns a new {@link ConsistentHash} with updated memberships. * * @param member the member to remove from the consistent hash * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash without(Member member) { Assert.notNull(member, () -> "Member may not be null"); if (!members.containsKey(member.name())) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.remove(member.name()); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
/** * Deregisters the given {@code member} and returns a new {@link ConsistentHash} with updated memberships. * * @param member the member to remove from the consistent hash * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash without(Member member) { Assert.notNull(member, () -> "Member may not be null"); if (!members.containsKey(member.name())) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.remove(member.name()); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
/** * Returns a ConsistentHash with the given additional <code>nodeName</code>, which is given * <code>segmentCount</code> segments on the ring. A registration of a node will completely override any previous * registration known for that node. * * @param nodeName The name of the node to add. This will be used to compute the segments * @param segmentCount The number of segments to add the given node * @param supportedCommandTypes The fully qualified names of command (payload) types this node supports * @return a ConsistentHash with the given additional node */ public ConsistentHash withAdditionalNode(String nodeName, int segmentCount, Set<String> supportedCommandTypes) { TreeMap<String, Member> newHashes = new TreeMap<String, Member>(hashToMember); Iterator<Map.Entry<String, Member>> iterator = newHashes.entrySet().iterator(); while (iterator.hasNext()) { if (nodeName.equals(iterator.next().getValue().name())) { iterator.remove(); } } Member node = new Member(nodeName, segmentCount, supportedCommandTypes); for (String key : node.hashes()) { newHashes.put(key, node); } return new ConsistentHash(newHashes); }
/** * Registers the given {@code member} with given {@code loadFactor} and {@code commandFilter} if it is not * already contained in the {@link ConsistentHash}. It will return the current ConsistentHash if the addition is * a duplicate and returns a new ConsistentHash with updated memberships if it is not. * <p> * The relative loadFactor of the member determines the likelihood of being selected as a destination for a command. * * @param member the member to register * @param loadFactor the load factor of the new member * @param commandFilter filter describing which commands can be handled by the given member * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash with(Member member, int loadFactor, Predicate<? super CommandMessage<?>> commandFilter) { Assert.notNull(member, () -> "Member may not be null"); ConsistentHashMember newMember = new ConsistentHashMember(member, loadFactor, commandFilter); if (members.containsKey(member.name()) && newMember.equals(members.get(member.name()))) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.put(member.name(), newMember); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
/** * Registers the given {@code member} with given {@code loadFactor} and {@code commandFilter} if it is not * already contained in the {@link ConsistentHash}. It will return the current ConsistentHash if the addition is * a duplicate and returns a new ConsistentHash with updated memberships if it is not. * <p> * The relative loadFactor of the member determines the likelihood of being selected as a destination for a command. * * @param member the member to register * @param loadFactor the load factor of the new member * @param commandFilter filter describing which commands can be handled by the given member * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash with(Member member, int loadFactor, CommandMessageFilter commandFilter) { Assert.notNull(member, () -> "Member may not be null"); ConsistentHashMember newMember = new ConsistentHashMember(member, loadFactor, commandFilter); if (members.containsKey(member.name()) && newMember.equals(members.get(member.name()))) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.put(member.name(), newMember); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }