BloomFilter to String and back

Tags: , ,



I want to conver BloomFilter to String, store it and then get it from String. If I do it using just byte array, without converting to String – everything is ok:

    BloomFilter<Integer> filter = BloomFilter.create(
            Funnels.integerFunnel(),
            500,
            0.01);
    for (int i=0; i<400; i++) {
        filter.put(i);
    }

    System.out.println(filter.approximateElementCount());
    System.out.println(filter.expectedFpp());
    String s = "";
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    filter.writeTo(out);
    s = out.toString(Charset.defaultCharset());
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    BloomFilter<Integer> filter1 = BloomFilter.readFrom(in, Funnels.integerFunnel());
    System.out.println(filter1.approximateElementCount());
    System.out.println(filter1.expectedFpp());

I get equals output, but if I convert bytes to String and then String to bytes – the result is wrong, I get filter1.approximateElementCount() = 799 instead of 402.

ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes(Charset.defaultCharset()));

Is there a way to convert BloomFilter to String and back?

Answer

Converting bytes to a String and back is not always reversible in any Charset. You must use a tool such as Base64 (provided in Guava as BaseEncoding.base64()) to convert a byte array to a string in such a way that you can always convert it back correctly.



Source: stackoverflow