// Path: src/main/java/org/rakam/cache/hazelcast/hyperloglog/MurmurHash3.java
// public final class MurmurHash3 {
// 
//     private MurmurHash3() {
//     }
// 
//     /**
//      * Returns the MurmurHash3_x86_32 hash.
//      */
//     public static int murmurhash3x8632(byte[] data, int offset, int len, int seed) {
// 
//         int c1 = 0xcc9e2d51;
//         int c2 = 0x1b873593;
// 
//         int h1 = seed;
//         int roundedEnd = offset + (len & 0xfffffffc);  // round down to 4 byte block
// 
//         for (int i = offset; i < roundedEnd; i += 4) {
//             // little endian load order
//             int k1 = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | (data[i + 3] << 24);
//             k1 *= c1;
//             k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
//             k1 *= c2;
// 
//             h1 ^= k1;
//             h1 = (h1 << 13) | (h1 >>> 19);  // ROTL32(h1,13);
//             h1 = h1 * 5 + 0xe6546b64;
//         }
// 
//         // tail
//         int k1 = 0;
// 
//         switch (len & 0x03) {
//             case 3:
//                 k1 = (data[roundedEnd + 2] & 0xff) << 16;
//                 // fallthrough
//             case 2:
//                 k1 |= (data[roundedEnd + 1] & 0xff) << 8;
//                 // fallthrough
//             case 1:
//                 k1 |= data[roundedEnd] & 0xff;
//                 k1 *= c1;
//                 k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
//                 k1 *= c2;
//                 h1 ^= k1;
//             default:
//         }
// 
//         // finalization
//         h1 ^= len;
// 
//         // fmix(h1);
//         h1 ^= h1 >>> 16;
//         h1 *= 0x85ebca6b;
//         h1 ^= h1 >>> 13;
//         h1 *= 0xc2b2ae35;
//         h1 ^= h1 >>> 16;
// 
//         return h1;
//     }
// 
// }


import java.util.Collection;
import net.agkn.hll.HLL;
import org.rakam.cache.hazelcast.hyperloglog.MurmurHash3;
/**
 * Created by buremba <Burak Emre Kabakcı> on 10/07/14.
 */

package org.rakam.util;



public class HLLWrapper {
    final private static int SEED = 123456;
    private HLL hll;

    public HLLWrapper() {
        hll = new HLL(13/*log2m*/, 5/*registerWidth*/);
    }

    public HLLWrapper(byte[] bytes) {
        hll = HLL.fromBytes(bytes);
    }

    public long cardinality() {
        return hll.cardinality();
    }

    public void union(HLLWrapper hll) {
        this.hll.union(hll.hll);
    }

    public void addAll(Collection<String> coll) {
        for (String a : coll) {
            byte[] s = a.getBytes();
// Path: src/main/java/org/rakam/cache/hazelcast/hyperloglog/MurmurHash3.java
// public final class MurmurHash3 {
// 
//     private MurmurHash3() {
//     }
// 
//     /**
//      * Returns the MurmurHash3_x86_32 hash.
//      */
//     public static int murmurhash3x8632(byte[] data, int offset, int len, int seed) {
// 
//         int c1 = 0xcc9e2d51;
//         int c2 = 0x1b873593;
// 
//         int h1 = seed;
//         int roundedEnd = offset + (len & 0xfffffffc);  // round down to 4 byte block
// 
//         for (int i = offset; i < roundedEnd; i += 4) {
//             // little endian load order
//             int k1 = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | (data[i + 3] << 24);
//             k1 *= c1;
//             k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
//             k1 *= c2;
// 
//             h1 ^= k1;
//             h1 = (h1 << 13) | (h1 >>> 19);  // ROTL32(h1,13);
//             h1 = h1 * 5 + 0xe6546b64;
//         }
// 
//         // tail
//         int k1 = 0;
// 
//         switch (len & 0x03) {
//             case 3:
//                 k1 = (data[roundedEnd + 2] & 0xff) << 16;
//                 // fallthrough
//             case 2:
//                 k1 |= (data[roundedEnd + 1] & 0xff) << 8;
//                 // fallthrough
//             case 1:
//                 k1 |= data[roundedEnd] & 0xff;
//                 k1 *= c1;
//                 k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
//                 k1 *= c2;
//                 h1 ^= k1;
//             default:
//         }
// 
//         // finalization
//         h1 ^= len;
// 
//         // fmix(h1);
//         h1 ^= h1 >>> 16;
//         h1 *= 0x85ebca6b;
//         h1 ^= h1 >>> 13;
//         h1 *= 0xc2b2ae35;
//         h1 ^= h1 >>> 16;
// 
//         return h1;
//     }
// 
// }


// Path: src/main/java/org/rakam/util/HLLWrapper.java
import java.util.Collection;
import net.agkn.hll.HLL;
import org.rakam.cache.hazelcast.hyperloglog.MurmurHash3;

/**
 * Created by buremba <Burak Emre Kabakcı> on 10/07/14.
 */

package org.rakam.util;



public class HLLWrapper {
    final private static int SEED = 123456;
    private HLL hll;

    public HLLWrapper() {
        hll = new HLL(13/*log2m*/, 5/*registerWidth*/);
    }

    public HLLWrapper(byte[] bytes) {
        hll = HLL.fromBytes(bytes);
    }

    public long cardinality() {
        return hll.cardinality();
    }

    public void union(HLLWrapper hll) {
        this.hll.union(hll.hll);
    }

    public void addAll(Collection<String> coll) {
        for (String a : coll) {
            byte[] s = a.getBytes();
            hll.addRaw(MurmurHash3.murmurhash3x8632(s, 0, s.length, SEED));