是否有特定于URL的hashCode方法?

时间:2011-07-30 23:26:37

标签: java algorithm url caching hashcode

是否有办法实现内存高效的“ID生成”URL?

目前我的网址有一个缓存ala Set<String>,我可以轻松检查我的抓取工具是否已经解析了该网址。现在这需要大量内存,我用Set<Long>替换它并使用了URL的hashCode。现在的问题是,即使是40k的URL也有10个冲突。使用long而不是int hashCode的改进方法可以将它改为6次冲突,但特别是短网址在开始时看起来非常相似:

5852015146777169869 http://twitpic.com/5xuwuk vs. http://twitpic.com/5xuw7m 5852015146777169869

所以我最终得到了以下特定于URL的双重散列方法,它没有为2.5mio URL提供冲突,这对我来说很好:

public static long urlHashing(String str) {
    if (str.length() < 2)
        return str.hashCode();

    long val = longHashCode(str, 31, false);
    if (str.length() > 3)
        // use the end of the string because those short URLs
        // are often identical at the beginning
        return 43 * val + longHashCode(str.substring(str.length() / 2), 37, true);
    return val;
}

public static long longHashCode(String str, int num, boolean up) {
    int len = str.length();
    if (len == 0)
        return 0;

    long h = 0;
    // copying to a temp arry is a only a tiny bit slower in our case.
    // so this here is ~2ms faster for 40k urls
    if (up)
        for (int i = 0; i < len;) {
            h = num * h + str.charAt(i++);
        }
    else
        for (int i = len - 1; i >= 0;) {
            h = num * h + str.charAt(i--);
        }

    return h;
}

但现在我想知道:是否有一些关于URL特定散列算法的理论或(google;))论文?或者简单地说:我可以进一步减少URL的冲突,还是看到我当前的解决方案有任何问题或改进?

更新

  • 另一种方法是按照协议,地址和文件分隔URL,就像在new URL(str).hashCode()方法中完成一样(由于速度非常慢而无法直接使用 - &gt;它可以动态解析URL: /)
  • 请参阅squid-cache.orgCacheDigest explanation

2 个答案:

答案 0 :(得分:3)

如果你想要的东西一直有效,而不仅仅是大部分时间,短暂的哈希不会削减它。正如您所观察到的,在任何长度短于大约128位的情况下,即使理想的散列也会具有显着的冲突率。你所拥有的是一个扩展问题,你使用哈希码完成的只是减少常数因子 - 它仍然是O(n)。

听起来你的字符串有很多共同的前缀 - 你考虑使用trie来存储它们吗?

答案 1 :(得分:2)

您应该使用MD5 hash。碰撞率应该小得多。