fastutil: Deserialized OpenHashMap can hang forever in containsKey and get

Legal text required by my employer: “Not a Contribution”

It seems that if you serialize an OpenHashMap, then deserialize it, key lookup can go into an infinite loop.

Simple test case:

import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class FastUtilMapTest {

    public static void main(String[] args) throws Exception {
        Long2ObjectOpenHashMap<String> map1 = new Long2ObjectOpenHashMap<>(8, 1.0f);
        map1.put(13L, "13");
        map1.put(15L, "15");
        map1.put(10L, "10");
        map1.put(14L, "14");
        map1.put(16L, "16");
        map1.put(18L, "18");
        map1.put(17L, "17");
        map1.put(11L, "11");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(map1);
        oos.flush();
        oos.close();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        Long2ObjectOpenHashMap<?> map2 = (Long2ObjectOpenHashMap<?>) ois.readObject();
        System.out.println(map1.containsKey(12L));
        System.out.println(map2.containsKey(12L));
    }

}

This will print false once and then hang, spinning a CPU at 100%. Tested with 8.3.1.

It looks like the mask field might be calculated wrongly on deserialization – for map1 it’s 15, but for map2 it’s 7. I don’t know how dependent this is on the size, fill factor, etc., or the specifics of the keys – this particular size and key set happened to trigger it for me.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

Sorry for the bump. @andy-clegg I forgot that I actually implemented exactly this already, compatible with fastutil interfaces https://github.com/incaseoftrouble/naturals-util/blob/master/src/main/java/de/tum/in/naturals/set/IntArraySortedSet.java

The Int2DoubleSortedArrayMap(int capacity) constructor exactly allocates capacity many items. Its an int to double map but replacing key and/or value type shouldn’t be too much of an issue I guess.