`
小网客
  • 浏览: 1217695 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

把string映射到64位的hashcode值方法

 
阅读更多

可以参考 xmemcached 的实现,源码如下:

 

public enum HashAlgorithm {

        /**
         * Native hash (String.hashCode()).
         */
        NATIVE_HASH,
        /**
         * CRC32_HASH as used by the perl API. This will be more consistent both
         * across multiple API users as well as java versions, but is mostly likely
         * significantly slower.
         */
        CRC32_HASH,
        /**
         * FNV hashes are designed to be fast while maintaining a low collision
         * rate. The FNV speed allows one to quickly hash lots of data while
         * maintaining a reasonable collision rate.
         * 
         * @see http://www.isthe.com/chongo/tech/comp/fnv/
         * @see http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
         */
        FNV1_64_HASH,
        /**
         * Variation of FNV.
         */
        FNV1A_64_HASH,
        /**
         * 32-bit FNV1.
         */
        FNV1_32_HASH,
        /**
         * 32-bit FNV1a.
         */
        FNV1A_32_HASH,
        /**
         * MD5-based hash algorithm used by ketama.
         */
        KETAMA_HASH,

        /**
         * From mysql source
         */
        MYSQL_HASH,

        ELF_HASH,

        RS_HASH,

        /**
         * From lua source,it is used for long key
         */
        LUA_HASH,

        ELECTION_HASH,
        /**
         * The Jenkins One-at-a-time hash ,please see
         * http://www.burtleburtle.net/bob/hash/doobs.html
         */
        ONE_AT_A_TIME;

        private static final long FNV_64_INIT = 0xcbf29ce484222325L;
        private static final long FNV_64_PRIME = 0x100000001b3L;

        private static final long FNV_32_INIT = 2166136261L;
        private static final long FNV_32_PRIME = 16777619;

        /**
         * Compute the hash for the given key.
         * 
         * @return a positive integer hash
         */
        public long hash(final String k) {
                long rv = 0;
                switch (this) {
                case NATIVE_HASH:
                        rv = k.hashCode();
                        break;
                case CRC32_HASH:
                        // return (crc32(shift) >> 16) & 0x7fff;
                        CRC32 crc32 = new CRC32();
                        crc32.update(ByteUtils.getBytes(k));
                        rv = crc32.getValue() >> 16 & 0x7fff;
                        break;
                case FNV1_64_HASH: {
                        // Thanks to pierre@demartines.com for the pointer
                        rv = FNV_64_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv *= FNV_64_PRIME;
                                rv ^= k.charAt(i);
                        }
                }
                        break;
                case FNV1A_64_HASH: {
                        rv = FNV_64_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv ^= k.charAt(i);
                                rv *= FNV_64_PRIME;
                        }
                }
                        break;
                case FNV1_32_HASH: {
                        rv = FNV_32_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv *= FNV_32_PRIME;
                                rv ^= k.charAt(i);
                        }
                }
                        break;
                case FNV1A_32_HASH: {
                        rv = FNV_32_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv ^= k.charAt(i);
                                rv *= FNV_32_PRIME;
                        }
                }
                        break;
                case ELECTION_HASH:
                case KETAMA_HASH:
                        byte[] bKey = computeMd5(k);
                        rv = (long) (bKey[3] & 0xFF) << 24 | (long) (bKey[2] & 0xFF) << 16
                                        | (long) (bKey[1] & 0xFF) << 8 | bKey[0] & 0xFF;
                        break;

                case MYSQL_HASH:
                        int nr2 = 4;
                        for (int i = 0; i < k.length(); i++) {
                                rv ^= ((rv & 63) + nr2) * k.charAt(i) + (rv << 8);
                                nr2 += 3;
                        }
                        break;
                case ELF_HASH:
                        long x = 0;
                        for (int i = 0; i < k.length(); i++) {
                                rv = (rv << 4) + k.charAt(i);
                                if ((x = rv & 0xF0000000L) != 0) {
                                        rv ^= x >> 24;
                                        rv &= ~x;
                                }
                        }
                        rv = rv & 0x7FFFFFFF;
                        break;
                case RS_HASH:
                        long b = 378551;
                        long a = 63689;
                        for (int i = 0; i < k.length(); i++) {
                                rv = rv * a + k.charAt(i);
                                a *= b;
                        }
                        rv = rv & 0x7FFFFFFF;
                        break;
                case LUA_HASH:
                        int step = (k.length() >> 5) + 1;
                        rv = k.length();
                        for (int len = k.length(); len >= step; len -= step) {
                                rv = rv ^ (rv << 5) + (rv >> 2) + k.charAt(len - 1);
                        }
                case ONE_AT_A_TIME:
                        try {
                                int hash = 0;
                                for (byte bt : k.getBytes("utf-8")) {
                                        hash += (bt & 0xFF);
                                        hash += (hash << 10);
                                        hash ^= (hash >>> 6);
                                }
                                hash += (hash << 3);
                                hash ^= (hash >>> 11);
                                hash += (hash << 15);
                                return hash;
                        } catch (UnsupportedEncodingException e) {
                                throw new IllegalStateException("Hash function error", e);
                        }
                default:
                        assert false;
                }

                return rv & 0xffffffffL; /* Truncate to 32-bits */
        }

        /**
         * Get the md5 of the given key.
         */
        public static byte[] computeMd5(String k) {
                MessageDigest md5;
                try {
                        md5 = MessageDigest.getInstance("MD5");
                } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException("MD5 not supported", e);
                }
                md5.reset();
                md5.update(ByteUtils.getBytes(k));
                return md5.digest();
        }

        // public static void main(String[] args) {
        // HashAlgorithm alg=HashAlgorithm.CRC32_HASH;
        // long h=0;
        // long start=System.currentTimeMillis();
        // for(int i=0;i<100000;i++)
        // h=alg.hash("MYSQL_HASH");
        // System.out.println(System.currentTimeMillis()-start);
        // }
}
1
4
分享到:
评论

相关推荐

    Hibernate注释大全收藏

    AUTO 生成器,适用与可移值的应用,多个@Id可以共享同一个 identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator 和 @TableGenerator 可以配置不同的 identifier 生成器。 table=...

    hibernate-types:Hibernate Types库为您提供了Hibernate ORM核心不支持的其他类型

    将JSON列类型映射到List或Map&lt;String&gt; ,需要确保POJO类型覆盖默认的equals和hashCode方法,并根据JSON对象的内容实现它们。 否则,Hibernate脏检查机制可能会触发意外的UPDATE语句。 查看。 Oracle 您应该使用...

    Hibernate中文API大全

    元素允许你映射一个组件类作为一个Map的key,前提是你必须正确的在这个类中重写了hashCode() 和 equals()方法。 8.4. 组件作为联合标识符(Components as composite identifiers) 你可以使用一个组件作为一个实体类...

    Android 对Map按key和value分别排序的实例

    TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 HashMap的值是没有顺序的,它是按照...

    Java HashMap

    HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。 HashMap 是无序的,即不会记录插入的顺序。 HashMap 继承于AbstractMap,实现了 ...

    javaSE代码实例

    14.6.3 equals与hashCode方法重写规定的作用 288 14.6.4 LinkedHashSet类的使用 291 14.6.5 SortedSet接口与TreeSet类 292 14.6.6 自定义满足Sorted集合的类 293 14.6.7 定制SortedSet的排序规则 296 14.6...

    BasicHashMap

    基本哈希图带有链接列表的哈希映射以处理冲突,这是作为练习而创建的。 支持泛型类型。 使用Java hashCode和java.util.LinkedList构建。用法实例化BasicHashMap&lt; String&gt; map = new BasicHashMap&lt; String&gt; (); 存储...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例106 简化hashCode()方法的重写 130 实例107 使用字符串输出对象 132 实例108 简化toString()方法的重写 133 5.6 克隆与序列化 134 实例109 Java对象的假克隆 134 实例110 Java对象的浅克隆 135 实例111 Java对象...

    Java常见面试题208道.docx

    十四、RabbitMQ 135.rabbitmq 的使用场景有哪些? 136.rabbitmq 有哪些重要的角色? 137.rabbitmq 有哪些重要的组件? 138.rabbitmq 中 vhost 的作用是什么? 139.rabbitmq 的消息是怎么发送的? 140.rabbitmq 怎么...

    Java学习笔记-个人整理的

    {5.2.1}将浮点数四舍五入到指定精度}{98}{subsection.5.2.1} {6}Exception}{99}{chapter.6} {6.1}\ttfamily try-catch}{99}{section.6.1} {6.2}\ttfamily finally}{100}{section.6.2} {6.3}\ttfamily throws}{...

Global site tag (gtag.js) - Google Analytics