「Consistent Hashingをためす」の編集履歴(バックアップ)一覧に戻る
public class Main { private static String search( NavigableMap<BigInteger, String> circle, BigInteger rec ){ // circleをNavigableMapを使用し、ceilingKeyによりもっとも近いkeyを取得 BigInteger key = circle.ceilingKey(rec); if( key == null ){ // 指定されたレコードがkeyの最大値を越える場合は最小ノードに入れる return (String)circle.get(circle.firstKey()); }else{ // ノードの最大値を越える場合は最小ノードに入れる return (String)circle.get(key); } } private static BigInteger getHash( String value ) throws NoSuchAlgorithmException{ int ret = 0; MessageDigest digest = MessageDigest.getInstance( "md5" ); byte[] byteHash = digest.digest(value.getBytes()); return new BigInteger(byteHash); } public static void main(String[] args) throws NoSuchAlgorithmException { int numOfReplicants = 0; NavigableMap<BigInteger, String> circle = new TreeMap<BigInteger, String>(); SortedMap<String, List> nodesmap = new TreeMap<String, List>(); List<String> alphalist = Arrays.asList( "A","B","C","D","E","F","G","H","I","J","K","L","M", "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); for( int i = 0; i < args.length; i++ ){ nodesmap.put( args[i], new LinkedList<String>()); } for( String node : nodesmap.keySet() ){ circle.put( getHash(node), node ); } for( String str : alphalist ){ String node = search(circle, getHash(str)); if( !nodesmap.containsKey(node)){ List<String> asciiList = new LinkedList<String>(); asciiList.add(str); nodesmap.put(node, asciiList); }else{ nodesmap.get(node).add(str); } } for( String node : nodesmap.keySet()){ System.out.print(node + " "); List<String> asciiList = nodesmap.get(node); for( String strascii : asciiList ){ System.out.print(strascii + " "); } System.out.print("\n"); } } }
$ java Main n1 n2 n3 n4 <-- 引数はノード名です。 n1 H T n2 A B F K M N P S U V W Y n3 C D E J O Q X Z n4 G I L R
$ java Main n1 n2 n3 n1 H T n2 A B F K M N P S U V W Y n3 C D E G I J L O Q R X Z
public class Main_Vnode { private static String search( NavigableMap<BigInteger, String> circle, BigInteger rec ){ // circleをNavigableMapに変更し、ceilingKeyにより、もっとも近いkeyを取得 BigInteger key = circle.ceilingKey(rec); if( key == null ){ // 指定されたレコードがkeyの最大値を越える場合は最小ノードに入れる return (String)circle.get(circle.firstKey()); }else{ // ノードの最大値を越える場合は最小ノードに入れる return (String)circle.get(key); } } private static BigInteger getHash( String value ) throws NoSuchAlgorithmException{ int ret = 0; MessageDigest digest = MessageDigest.getInstance( "md5" ); byte[] byteHash = digest.digest(value.getBytes()); return new BigInteger(byteHash); } public static void main(String[] args) throws NoSuchAlgorithmException { int numOfReplicants = 0; NavigableMap<BigInteger, String> circle = new TreeMap<BigInteger, String>(); SortedMap<String, List> nodesmap = new TreeMap<String, List>(); List<String> alphalist = Arrays.asList( "A","B","C","D","E","F","G","H","I","J","K","L","M", "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); for( int i = 0; i < args.length; i++ ){ if( i == 0){ numOfReplicants = Integer.valueOf(args[0]); } else { nodesmap.put( args[i], new LinkedList<String>()); } } for( String node : nodesmap.keySet() ){ circle.put( getHash(node), node ); for(int i=1; i <= numOfReplicants; i++){ circle.put( getHash(node + '_' + i), node ); } } for( String str : alphalist ){ String node = search(circle, getHash(str)); if( !nodesmap.containsKey(node)){ List<String> asciiList = new LinkedList<String>(); asciiList.add(str); nodesmap.put(node, asciiList); }else{ nodesmap.get(node).add(str); } } for( String node : nodesmap.keySet()){ System.out.print(node + " "); List<String> asciiList = nodesmap.get(node); for( String strascii : asciiList ){ System.out.print(strascii + " "); } System.out.print("\n"); } } }
$ java Main_Vnode 100 n1 n2 n3 n4 <---第一引数が1ノードあたりの仮想ノード数で、その後ろの引数はノード名です。 n1 A E F O P Q U V n2 B H S T Y n3 C K L M N Z n4 D G I J R W X
$ java Main_Vnode 100 n1 n2 n3 n1 A D E F O P Q U V n2 B H I S T W Y n3 C G J K L M N R X Z