Package voldemort.routing

Source Code of voldemort.routing.BaseStoreRoutingPlan

/*
* Copyright 2013 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package voldemort.routing;

import java.util.List;

import voldemort.VoldemortException;
import voldemort.cluster.Cluster;
import voldemort.cluster.Node;
import voldemort.store.StoreDefinition;
import voldemort.utils.ByteUtils;
import voldemort.utils.Utils;

/**
* This class wraps up a Cluster object and a StoreDefinition. The methods are
* effectively helper or util style methods for querying the routing plan that
* will be generated for a given routing strategy upon store and cluster
* topology information.
*
* This object may be constructed in the fast path (e.g., during proxy'ing) and
* so this object must be fast/simple to construct. Invocations of getters to
* find replica lists and n-aries can be O(number of replicas).
*
* The intermingling of key-based interfaces and partition-based interfaces is
* ugly in this class. Partition-based interfaces should be in an underlying
* class and then key-based interfaces should wrap those up. Or, all of these
* types of class should implement the getMasterPartition(byte[]) interface from
* RoutingStrategy. Then the caller always does translation from key to
* partition ID, and the *StoreRouting* classes only offer partition-based
* interfaces.
*/
// TODO: Should find a better name for this class. Need to do same for what is
// currently StoreRoutingPlan. Suggestions thus far for this class:
// ProxyRoutingPlan, ProxyStoreRouter, SimpleStoreRouter, ...
public class BaseStoreRoutingPlan {

    private final Cluster cluster;
    private final StoreDefinition storeDefinition;
    private final RoutingStrategy routingStrategy;

    public BaseStoreRoutingPlan(Cluster cluster, StoreDefinition storeDefinition) {
        this.cluster = cluster;
        this.storeDefinition = storeDefinition;
        this.routingStrategy = new RoutingStrategyFactory().updateRoutingStrategy(storeDefinition,
                                                                                  cluster);
    }

    public Cluster getCluster() {
        return cluster;
    }

    public StoreDefinition getStoreDefinition() {
        return storeDefinition;
    }

    /**
     * Determines master partition ID for the key.
     *
     * @param key
     * @return master parition id
     */
    public int getMasterPartitionId(final byte[] key) {
        return this.routingStrategy.getMasterPartition(key);
    }

    /**
     * Given a key that belong to a given node, returns a number n (< zone
     * replication factor), such that the given node holds the key as the nth
     * replica of the given zone
     *
     * eg: if the method returns 1, then given node hosts the key as the zone
     * secondary in the given zone
     *
     * @param zoneId
     * @param nodeId
     * @param key
     * @return zone n-ary level for key hosted on node id in zone id.
     */
    // TODO: add unit test.
    public int getZoneNAry(int zoneId, int nodeId, byte[] key) {
        if(cluster.getNodeById(nodeId).getZoneId() != zoneId) {
            throw new VoldemortException("Node " + nodeId + " is not in zone " + zoneId
                                         + "! The node is in zone "
                                         + cluster.getNodeById(nodeId).getZoneId());
        }

        List<Node> replicatingNodes = this.routingStrategy.routeRequest(key);
        int zoneNAry = -1;
        for(Node node: replicatingNodes) {
            // bump up the replica number once you encounter a node in the given
            // zone
            if(node.getZoneId() == zoneId) {
                zoneNAry++;
            }
            // we are done when we find the given node
            if(node.getId() == nodeId) {
                return zoneNAry;
            }
        }
        if(zoneNAry > -1) {
            throw new VoldemortException("Node " + nodeId + " not a replica for the key "
                                         + ByteUtils.toHexString(key) + " in given zone " + zoneId);
        } else {
            throw new VoldemortException("Could not find any replicas for the key "
                                         + ByteUtils.toHexString(key) + " in given zone " + zoneId);
        }
    }

    /**
     * Given a key and a zoneNary (< zone replication factor), figure out the
     * node that contains the key as the nth replica in the given zone.
     *
     * @param zoneId
     * @param zoneNary
     * @param key
     * @return node id that hosts zone n-ary replica for the key
     */
    // TODO: add unit test.
    public int getNodeIdForZoneNary(int zoneId, int zoneNary, byte[] key) {
        List<Node> replicatingNodes = this.routingStrategy.routeRequest(key);
        int zoneNAry = -1;
        for(Node node: replicatingNodes) {
            // bump up the counter if we encounter a replica in the given zone;
            // return current node if counter now matches requested
            if(node.getZoneId() == zoneId) {
                zoneNAry++;

                if(zoneNAry == zoneNary) {
                    return node.getId();
                }
            }
        }
        if(zoneNAry == -1) {
            throw new VoldemortException("Could not find any replicas for the key "
                                         + ByteUtils.toHexString(key) + " in given zone " + zoneId);
        } else {
            throw new VoldemortException("Could not find " + (zoneNary + 1)
                                         + " replicas for the key " + ByteUtils.toHexString(key)
                                         + " in given zone " + zoneId + ". Only found "
                                         + (zoneNAry + 1));
        }
    }

    /**
     * Determines the list of nodes that the key replicates to
     *
     * @param key
     * @return list of nodes that key replicates to
     */
    public List<Integer> getReplicationNodeList(final byte[] key) {
        return Utils.nodeListToNodeIdList(this.routingStrategy.routeRequest(key));
    }

}
TOP

Related Classes of voldemort.routing.BaseStoreRoutingPlan

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.