package com.github.zangxiaoqiang.dfc.locator; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; import com.github.zangxiaoqiang.common.conf.ConfigurationManager; import com.github.zangxiaoqiang.common.conf.GitConfiguration; import com.github.zangxiaoqiang.dfc.CacheNode; import com.github.zangxiaoqiang.dfc.HashAlgorithm; import com.github.zangxiaoqiang.dfc.server.DataNode; import com.github.zangxiaoqiang.dfc.server.Partition; import com.github.zangxiaoqiang.dfc.utils.Context; public final class KetamaNodeLocator2 extends CommonNodeLocator{ static GitConfiguration conf = ConfigurationManager.getDefaultConfig(); private TreeMap<Long, CacheNode> ketamaCacheNodes; private HashAlgorithm hashAlg; //private int numReps = 160; public static final String SERVER_FILE = "server.properties"; private int cacheNodeNumber ; private int allPartitionNumber = 0 ; private List<DataNode> allDataNodes; private int replication; public KetamaNodeLocator2(HashAlgorithm alg) { hashAlg = alg; ketamaCacheNodes = new TreeMap<Long, CacheNode>(); //numReps = nodeCopies; allDataNodes = getDataNodes(); replication = Integer.valueOf(conf.getValue("data.replication", "3")); cacheNodeNumber = (int) Math.ceil((double)allPartitionNumber/(double)replication); for(int i = 0 ; i < cacheNodeNumber; i++){ CacheNode cn = new CacheNode("CacheNode-" + i); byte[] md5 = hashAlg.computeMd5(cn.getName()); long m = hashAlg.hash(md5, 0); ketamaCacheNodes.put(m, cn); } for (DataNode dn : allDataNodes) { for (int i = 0 ; i < dn.getPartitionSize(); i++) { Partition p = new Partition(dn.getHostname() + "-Partition-" + i); dn.addPartition(p); p.setDataNode(dn); CacheNode cn = getCacheNode(p.getName()); cn.addPartition(p); p.setCacheNode(cn); } } } private List<DataNode> getDataNodes() { allPartitionNumber = 0 ; List<DataNode> nodes = new ArrayList<DataNode>(); List<String> serverList = Context.loadFile(SERVER_FILE); for (String server : serverList) { String hostname = server.split(":")[0]; int port = Integer.valueOf(server.split(":")[1]); DataNode node = new DataNode(hostname, port); node.setPartitionSize(Integer.valueOf(server.split(":")[2])); allPartitionNumber += Integer.valueOf(server.split(":")[2]); nodes.add(node); } return nodes; } @Override public CacheNode getCacheNode(final String filePath) { CacheNode rv = getCacheNodeByKey(getPathHash(hashAlg, filePath)); return rv; } private CacheNode getCacheNodeByKey(long hash) { final CacheNode rv; Long key = hash; if (!ketamaCacheNodes.containsKey(key)) { // SortedMap<Long, Node> tailMap = ketamaNodes.tailMap(key); // if (tailMap.isEmpty()) { // key = ketamaNodes.firstKey(); // } else { // key = tailMap.firstKey(); // } // For JDK1.6 version key = ketamaCacheNodes.ceilingKey(key); if (key == null) { key = ketamaCacheNodes.firstKey(); } } rv = ketamaCacheNodes.get(key); return rv; } }