1

この Web サイトで定義されているロジックを実装しようとしています。手順の 1 つは次のとおりです。

  • 各サーバー文字列を複数 (100 ~ 200) の unsigned int にハッシュする

しかし、私はこれと混同しています。ロジックを手動で実装できるように、これが何を意味するのか誰か教えてください。

// This count is always 2 as per my current setup
int availableservers = Client.getAvailableServers().size();  

String key = "MyKey";
int keyid = key.hashCode();
int v = keyid % 1;
String valess = (String) mcc.get(key,v);
4

3 に答える 3

3

あなたが参照した記事には、SVN コード ベースへのリンクが含まれています。

svn://svn.audioscrobbler.net/misc/ketama/

ここでは、Java 実装が含まれているようです。

svn://svn.audioscrobbler.net/misc/ketama/java_ketama/SockIOPool.java

コードでは、次のことがわかります。

for(long j = 0; j < factor; j++) {
  byte[] d = md5.digest((servers[i]+"-"+j).getBytes());
  for(int h=0;h<4;h++) {
    Long k = 
        ((long)(d[3+h*4]&0xFF) << 24)
      | ((long)(d[2+h*4]&0xFF) << 16)
      | ((long)(d[1+h*4]&0xFF) << 8)
      | ((long)(d[0+h*4]&0xFF));
    buckets.put(k, servers[i]);
    log.debug( "++++ added " + servers[i] + " to server bucket" );
  }             
}

factorこのコードは、サーバーごとに合計のハッシュを作成しています。ハッシュする前に、現在の値をjstringに追加する for ループに注意してください。server[i]

これを Frank Pavageau の回答と組み合わせると、何が起こっているのかすぐに理解できるはずです。

于 2012-10-28T08:31:00.903 に答える
2

ケタマのハッシュは MD5 で計算されていると思います。ここでサンプル実装を見つけました

public static Long md5HashingAlg(String key) {
  MessageDigest md5 = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException( "md5 algorythm found");            
        }
    }
    md5.reset();
    md5.update(key.getBytes());
    byte[] bKey = md5.digest();
    long res = ((long)(bKey[3]&0xFF) << 24) | ((long)(bKey[2]&0xFF) << 16) | ((long)(bKey[1]&0xFF) << 8) | (long)(bKey[0]&0xFF);
    return res;
}
于 2012-10-28T08:29:11.607 に答える
1

Duncan の言うとおりです。ソースをチェックして、この特定の実装がどのように機能するかを確認してください。

ただし、概念的には、使用するハッシュ アルゴリズムが何であれ、同じキーに基づく複数のハッシュが必要な場合は、キーを複数の「定数」、または少なくとも既知で反復可能な値と連結するだけで済みます。

String key = "MyKey";
List<Integer> hashes = new ArrayList<>();
for (String s : Arrays.asList("", "extra1", "extra2")) {
    hashes.add((key + s).hashCode());
}

これは、記事の用語を再利用するために、整数の「連続体」の周りにハッシュを分散することと同じです。したがって、hashCode() を実装できるのと同じ方法で、そのようにすることもできます。

String key "MyKey";
List<Integer> hashes = new ArrayList<>();
int hash = key.hashCode();
for (int i = 0; i < 100; i++) {
    hashes.add(hash);
    hash = 31 * hash + 1234567;
}
于 2012-10-28T08:38:56.157 に答える