All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.distribution.ch.impl.AbstractConsistentHashFactory Maven / Gradle / Ivy

package org.infinispan.distribution.ch.impl;

import org.infinispan.commons.hash.Hash;
import org.infinispan.distribution.ch.ConsistentHash;
import org.infinispan.distribution.ch.ConsistentHashFactory;
import org.infinispan.remoting.transport.Address;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author Radim Vansa <[email protected]>
 */
public abstract class AbstractConsistentHashFactory implements ConsistentHashFactory {
   protected void checkCapacityFactors(List
members, Map capacityFactors) { if (capacityFactors != null) { float totalCapacity = 0; for (Address node : members) { Float capacityFactor = capacityFactors.get(node); if (capacityFactor == null || capacityFactor < 0) throw new IllegalArgumentException("Invalid capacity factor for node " + node); totalCapacity += capacityFactor; } if (totalCapacity == 0) throw new IllegalArgumentException("There must be at least one node with a non-zero capacity factor"); } } /** * @return The worst primary owner, or {@code null} if the remaining nodes own 0 segments. */ protected Address findWorstPrimaryOwner(Builder builder, List
nodes) { Address worst = null; float maxSegmentsPerCapacity = -1; for (Address owner : nodes) { float capacityFactor = builder.getCapacityFactor(owner); if (builder.getPrimaryOwned(owner) - 1 >= capacityFactor * maxSegmentsPerCapacity) { worst = owner; maxSegmentsPerCapacity = capacityFactor != 0 ? (builder.getPrimaryOwned(owner) - 1) / capacityFactor : 0; } } return worst; } /** * @return The candidate with the worst primary-owned segments/capacity ratio that is also not in the excludes list. */ protected Address findNewPrimaryOwner(Builder builder, Collection
candidates, Address primaryOwner) { float initialCapacityFactor = primaryOwner != null ? builder.getCapacityFactor(primaryOwner) : 0; // We want the owned/capacity ratio of the actual primary owner after removing the current segment to be bigger // than the owned/capacity ratio of the new primary owner after adding the current segment, so that a future pass // won't try to switch them back. Address best = null; float bestSegmentsPerCapacity = initialCapacityFactor != 0 ? (builder.getPrimaryOwned(primaryOwner) - 1) / initialCapacityFactor : Float.MAX_VALUE; for (Address candidate : candidates) { int primaryOwned = builder.getPrimaryOwned(candidate); float capacityFactor = builder.getCapacityFactor(candidate); if ((primaryOwned + 1) <= capacityFactor * bestSegmentsPerCapacity) { best = candidate; bestSegmentsPerCapacity = (primaryOwned + 1) / capacityFactor; } } return best; } static abstract class Builder { protected final Hash hashFunction; protected final OwnershipStatistics stats; protected final List
members; protected final Map capacityFactors; // For debugging protected int modCount = 0; public Builder(Hash hashFunction, OwnershipStatistics stats, List
members, Map capacityFactors) { this.hashFunction = hashFunction; this.stats = stats; this.members = members; this.capacityFactors = capacityFactors; } public Builder(Builder other) { this.hashFunction = other.hashFunction; this.members = other.members; this.capacityFactors = other.capacityFactors; this.stats = new OwnershipStatistics(other.stats); } public List
getMembers() { return members; } public int getNumNodes() { return getMembers().size(); } public abstract int getPrimaryOwned(Address candidate); public Map getCapacityFactors() { return capacityFactors; } public float getCapacityFactor(Address node) { return capacityFactors != null ? capacityFactors.get(node) : 1; } public float getTotalCapacity() { if (capacityFactors == null) return getNumNodes(); float totalCapacity = 0; for (Address node : members) { totalCapacity += capacityFactors.get(node); } return totalCapacity; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy