2

I have a use case where I'd like to use opaque byte[] as keys into a MapDb. I discovered this - Using a byte array as Map key - limitation quickly; and wonder which approach is recommended.

I'd rather not create a bunch of interim objects and serialization overhead, but it seems like ByteBuffer.wrap(my_bytes) is where Java is pointing me.

I'm hoping one of the core devs of MapDB can weigh in on this or a ByteBuffer JVM guru.

Community
  • 1
  • 1
Nino Walker
  • 2,742
  • 22
  • 30

2 Answers2

5

MapDB author here.

It is possible to use byte[] without wrappers. There is Hasher which handles hashCode and equals methods for HTreeMap:

    Map map = db.createHashMap("map")
            .hasher(Hasher.BYTE_ARRAY)
            .keySerializer(Serializer.BYTE_ARRAY)
            .makeOrGet();
Jan Kotek
  • 1,084
  • 7
  • 4
  • I know this is old, but for future reference: `Hasher` doesn't exist anymore, but I believe the `Serializer.BYTE_ARRAY` will handle this automatically. I'll let Jan correct me if I'm wrong. – Martín Coll May 31 '19 at 19:05
0

Actually, I can't see anything wrong in the approach suggested in the linked answer. They say you have to wrap your byte array into some class having predictable and consistent hashCode() and equals() implementations. Someone suggests using String or ByteBuffer, but that would definitely be a hack and may screw up at some point. This simple wrapper may be enough (note that I made a defensive copy of the input bytes to prevent modifications that will alter hashCode() and equals() computations: key in maps must be immutable):

class HashtableByteArray {

  private final byte[] data;

  public HashtableByteArray(byte[] data) {
    this.data = Arrays.copyOf(data, data.length);
  }

  public int hashCode() {
    return Arrays.hashCode(data);
  }

  public boolean equals(Object other) {
    return other instanceof HashtableByteArray
      && Arrays.equals(data, ((HashtableByteArray) other).data);
  }
}

This sample relies heavily on the utils in the Arrays class, but you can certainly build your version with optimized hashCode() and equals() that better suite your needs.

Raffaele
  • 20,627
  • 6
  • 47
  • 86
  • This is a good recommendation in the general case. Having now read the code for `ByteBuffer` this implementation has the lowest overhead of any wrapping solution. `ByteBuffer` tracks a number of fields that are unnecessary for basic consumption. – Nino Walker Dec 20 '13 at 01:37