11cb0ef41Sopenharmony_ci/**
21cb0ef41Sopenharmony_ci * @preserve
31cb0ef41Sopenharmony_ci * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013)
41cb0ef41Sopenharmony_ci *
51cb0ef41Sopenharmony_ci * @author <a href="mailto:jensyt@gmail.com">Jens Taylor</a>
61cb0ef41Sopenharmony_ci * @see http://github.com/homebrewing/brauhaus-diff
71cb0ef41Sopenharmony_ci * @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
81cb0ef41Sopenharmony_ci * @see http://github.com/garycourt/murmurhash-js
91cb0ef41Sopenharmony_ci * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
101cb0ef41Sopenharmony_ci * @see http://sites.google.com/site/murmurhash/
111cb0ef41Sopenharmony_ci */
121cb0ef41Sopenharmony_ci(function(){
131cb0ef41Sopenharmony_ci    var cache;
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci    // Call this function without `new` to use the cached object (good for
161cb0ef41Sopenharmony_ci    // single-threaded environments), or with `new` to create a new object.
171cb0ef41Sopenharmony_ci    //
181cb0ef41Sopenharmony_ci    // @param {string} key A UTF-16 or ASCII string
191cb0ef41Sopenharmony_ci    // @param {number} seed An optional positive integer
201cb0ef41Sopenharmony_ci    // @return {object} A MurmurHash3 object for incremental hashing
211cb0ef41Sopenharmony_ci    function MurmurHash3(key, seed) {
221cb0ef41Sopenharmony_ci        var m = this instanceof MurmurHash3 ? this : cache;
231cb0ef41Sopenharmony_ci        m.reset(seed)
241cb0ef41Sopenharmony_ci        if (typeof key === 'string' && key.length > 0) {
251cb0ef41Sopenharmony_ci            m.hash(key);
261cb0ef41Sopenharmony_ci        }
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci        if (m !== this) {
291cb0ef41Sopenharmony_ci            return m;
301cb0ef41Sopenharmony_ci        }
311cb0ef41Sopenharmony_ci    };
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    // Incrementally add a string to this hash
341cb0ef41Sopenharmony_ci    //
351cb0ef41Sopenharmony_ci    // @param {string} key A UTF-16 or ASCII string
361cb0ef41Sopenharmony_ci    // @return {object} this
371cb0ef41Sopenharmony_ci    MurmurHash3.prototype.hash = function(key) {
381cb0ef41Sopenharmony_ci        var h1, k1, i, top, len;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci        len = key.length;
411cb0ef41Sopenharmony_ci        this.len += len;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci        k1 = this.k1;
441cb0ef41Sopenharmony_ci        i = 0;
451cb0ef41Sopenharmony_ci        switch (this.rem) {
461cb0ef41Sopenharmony_ci            case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0;
471cb0ef41Sopenharmony_ci            case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0;
481cb0ef41Sopenharmony_ci            case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0;
491cb0ef41Sopenharmony_ci            case 3:
501cb0ef41Sopenharmony_ci                k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0;
511cb0ef41Sopenharmony_ci                k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0;
521cb0ef41Sopenharmony_ci        }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci        this.rem = (len + this.rem) & 3; // & 3 is same as % 4
551cb0ef41Sopenharmony_ci        len -= this.rem;
561cb0ef41Sopenharmony_ci        if (len > 0) {
571cb0ef41Sopenharmony_ci            h1 = this.h1;
581cb0ef41Sopenharmony_ci            while (1) {
591cb0ef41Sopenharmony_ci                k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff;
601cb0ef41Sopenharmony_ci                k1 = (k1 << 15) | (k1 >>> 17);
611cb0ef41Sopenharmony_ci                k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff;
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci                h1 ^= k1;
641cb0ef41Sopenharmony_ci                h1 = (h1 << 13) | (h1 >>> 19);
651cb0ef41Sopenharmony_ci                h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff;
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci                if (i >= len) {
681cb0ef41Sopenharmony_ci                    break;
691cb0ef41Sopenharmony_ci                }
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci                k1 = ((key.charCodeAt(i++) & 0xffff)) ^
721cb0ef41Sopenharmony_ci                     ((key.charCodeAt(i++) & 0xffff) << 8) ^
731cb0ef41Sopenharmony_ci                     ((key.charCodeAt(i++) & 0xffff) << 16);
741cb0ef41Sopenharmony_ci                top = key.charCodeAt(i++);
751cb0ef41Sopenharmony_ci                k1 ^= ((top & 0xff) << 24) ^
761cb0ef41Sopenharmony_ci                      ((top & 0xff00) >> 8);
771cb0ef41Sopenharmony_ci            }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci            k1 = 0;
801cb0ef41Sopenharmony_ci            switch (this.rem) {
811cb0ef41Sopenharmony_ci                case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16;
821cb0ef41Sopenharmony_ci                case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8;
831cb0ef41Sopenharmony_ci                case 1: k1 ^= (key.charCodeAt(i) & 0xffff);
841cb0ef41Sopenharmony_ci            }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci            this.h1 = h1;
871cb0ef41Sopenharmony_ci        }
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci        this.k1 = k1;
901cb0ef41Sopenharmony_ci        return this;
911cb0ef41Sopenharmony_ci    };
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci    // Get the result of this hash
941cb0ef41Sopenharmony_ci    //
951cb0ef41Sopenharmony_ci    // @return {number} The 32-bit hash
961cb0ef41Sopenharmony_ci    MurmurHash3.prototype.result = function() {
971cb0ef41Sopenharmony_ci        var k1, h1;
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci        k1 = this.k1;
1001cb0ef41Sopenharmony_ci        h1 = this.h1;
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci        if (k1 > 0) {
1031cb0ef41Sopenharmony_ci            k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff;
1041cb0ef41Sopenharmony_ci            k1 = (k1 << 15) | (k1 >>> 17);
1051cb0ef41Sopenharmony_ci            k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff;
1061cb0ef41Sopenharmony_ci            h1 ^= k1;
1071cb0ef41Sopenharmony_ci        }
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci        h1 ^= this.len;
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci        h1 ^= h1 >>> 16;
1121cb0ef41Sopenharmony_ci        h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff;
1131cb0ef41Sopenharmony_ci        h1 ^= h1 >>> 13;
1141cb0ef41Sopenharmony_ci        h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff;
1151cb0ef41Sopenharmony_ci        h1 ^= h1 >>> 16;
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci        return h1 >>> 0;
1181cb0ef41Sopenharmony_ci    };
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci    // Reset the hash object for reuse
1211cb0ef41Sopenharmony_ci    //
1221cb0ef41Sopenharmony_ci    // @param {number} seed An optional positive integer
1231cb0ef41Sopenharmony_ci    MurmurHash3.prototype.reset = function(seed) {
1241cb0ef41Sopenharmony_ci        this.h1 = typeof seed === 'number' ? seed : 0;
1251cb0ef41Sopenharmony_ci        this.rem = this.k1 = this.len = 0;
1261cb0ef41Sopenharmony_ci        return this;
1271cb0ef41Sopenharmony_ci    };
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci    // A cached object to use. This can be safely used if you're in a single-
1301cb0ef41Sopenharmony_ci    // threaded environment, otherwise you need to create new hashes to use.
1311cb0ef41Sopenharmony_ci    cache = new MurmurHash3();
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci    if (typeof(module) != 'undefined') {
1341cb0ef41Sopenharmony_ci        module.exports = MurmurHash3;
1351cb0ef41Sopenharmony_ci    } else {
1361cb0ef41Sopenharmony_ci        this.MurmurHash3 = MurmurHash3;
1371cb0ef41Sopenharmony_ci    }
1381cb0ef41Sopenharmony_ci}());
139