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

io.zulia.server.index.DefaultNodeWeightComputation Maven / Gradle / Ivy

There is a newer version: 1.6.4
Show newest version
package io.zulia.server.index;

import com.google.common.util.concurrent.AtomicDouble;
import io.zulia.message.ZuliaBase.Node;
import io.zulia.message.ZuliaIndex;
import io.zulia.message.ZuliaIndex.IndexMapping;
import io.zulia.message.ZuliaIndex.IndexSettings;
import io.zulia.server.config.IndexService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class DefaultNodeWeightComputation implements NodeWeightComputation {

	public static final double REPLICA_WEIGHT_DELTA = 0.01;

	private final HashMap nodeWeightMap;

	public DefaultNodeWeightComputation(IndexService indexService, Node thisNode, Collection currentOtherNodesActive) throws Exception {

		Set activeNodes = new HashSet<>();
		activeNodes.add(thisNode);
		activeNodes.addAll(currentOtherNodesActive);

		HashMap weightMap = new HashMap<>();

		for (IndexSettings settings : indexService.getIndexes()) {

			weightMap.put(settings.getIndexName(), settings.getIndexWeight());

		}

		nodeWeightMap = new HashMap<>();

		for (IndexMapping indexMapping : indexService.getIndexMappings()) {
			Integer weightForIndex = weightMap.get(indexMapping.getIndexName());
			if (weightForIndex == null) {
				//index has an index mapping but not an index settings
				continue;
			}
			double indexShardWeight = weightForIndex / indexMapping.getNumberOfShards();
			for (ZuliaIndex.ShardMapping shardMapping : indexMapping.getShardMappingList()) {
				nodeWeightMap.computeIfAbsent(getNodeKey(shardMapping.getPrimaryNode()), k -> new AtomicDouble()).addAndGet(indexShardWeight);

				for (Node node : shardMapping.getReplicaNodeList()) {
					nodeWeightMap.computeIfAbsent(getNodeKey(node), k -> new AtomicDouble()).addAndGet(indexShardWeight - REPLICA_WEIGHT_DELTA);
				}
			}
		}

		for (Node node : activeNodes) {
			nodeWeightMap.computeIfAbsent(getNodeKey(node), k -> new AtomicDouble());
		}

		nodeWeightMap.keySet().retainAll(activeNodes.stream().map(this::getNodeKey).collect(Collectors.toSet()));

	}

	@Override
	public List getNodesSortedByWeight() {
		List> entries = new ArrayList<>(nodeWeightMap.entrySet());
		Collections.shuffle(entries);
		entries.sort(Map.Entry.comparingByValue(Comparator.comparingDouble(AtomicDouble::get)));
		return entries.stream().map(Map.Entry::getKey).collect(Collectors.toList());
	}

	private Node getNodeKey(Node primaryNode) {
		return Node.newBuilder().setServerAddress(primaryNode.getServerAddress()).setServicePort(primaryNode.getServicePort()).build();
	}

	@Override
	public void addShard(Node node, IndexSettings indexSettings, boolean primary) {

		int indexWeight = indexSettings.getIndexWeight() != 0 ? indexSettings.getIndexWeight() : 1;
		double indexShardWeight = (double) indexWeight / indexSettings.getNumberOfShards();
		if (!primary) {
			indexShardWeight = Math.max(0, indexShardWeight - REPLICA_WEIGHT_DELTA);
		}
		nodeWeightMap.computeIfAbsent(node, k -> new AtomicDouble()).addAndGet(indexShardWeight);

	}
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy