Why ChronicleMap doesn't use hashCode or equals to lookup keys?

522 views Asked by At
import net.openhft.chronicle.map.ChronicleMap;

import java.io.File;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class App {

    public static void main(String[] args) throws Exception  {

        Map<Point, Point> map1 = new ConcurrentHashMap<>();

        ChronicleMap<Point, Point> map2 = ChronicleMap
                .of(Point.class, Point.class)
                .name("map")
                .averageKey(new Point(10, 10))
                .averageValue(new Point(10, 10))
                .entries(50)
                .createPersistedTo(new File("c:/temp/map/param.dat"));

        Point key = new Point(12, 12);
        key.hashCode();

        map1.put(key, key);
        map2.put(key, key);

        System.out.println("ConcurrentHashMap.get returned " + map1.get(new Point(12, 12)));
        System.out.println("ChronicleMap.get returned " + map2.get(new Point(12, 12)));
    }
}

class Point implements Serializable {
    private int x = 0;
    private int y = 0;
    private int _hash = 0;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }


    @Override
    public String toString() {
        return super.toString() +  " {" + x + "," + y + "}";
    }

    @Override
    public int hashCode() {
        _hash = 1;
        _hash = _hash * 17 + x;
        _hash = _hash * 31 + y;
        return _hash;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof  Point) {
            return (x == ((Point) obj).getX()) && (y == ((Point) obj).getY());
        }
        return false;
    }
}

As you can see in the example above, ChronicleMap behaviour is a bit different from ConcurrentHashMap (same with HashMap) as it can't lookup keys with hashCode or equals.

can someone pinpoint what can be done to fix this ?

UPDATE; When executed, the program will return the following results:

ConcurrentHashMap.get returned App.Point@38f {12,12}
ChronicleMap.get returned null
1

There are 1 answers

6
Peter Lawrey On

ChronicleMap serialises the key and takes a 64-bit hash of the bytes.

A 64-bit hash is used as the map is designed for a very large number of keys eg. billions, whereas a 32-bit hash tends to have a high collision rate when you have millions of keys.

It can also use more advanced hashing strategies such as these https://github.com/OpenHFT/Zero-Allocation-Hashing

Note: Using Serializable is the least efficient way to do this but never the less is fine for this example.