package jalview.util; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import jalview.bin.Console; public class IdUtils { /** * id generating tools avoiding Random.nextLong() for JalviewJS. Avoids * collisions. */ public static enum IdType { GENERAL, PROGRESS; } private static int count = 0; private static Map> typeMap = new HashMap<>(); static { for (IdType t : IdType.values()) { typeMap.put(t, new HashSet<>()); } } public static long newId() { return newId(IdType.GENERAL, null); } public static long newId(IdType t) { return newId(t, null); } public static long newId(IdType t, Object o) { Set idSet = typeMap.get(t); long newId = 0; if (o == null) { // get a new hashCode -- not tied to an object. // Adding Integer.MAX_VALUE should avoid collisions with object generated // Ids. newId = Integer.MAX_VALUE + t.hashCode() + System.currentTimeMillis() + count; while (idSet.contains(newId)) { newId += count; } } else { // generate the hashcode tied to this object for this type newId = t.hashCode() + o.hashCode(); if (idSet.contains(newId)) { Console.debug("Using an existing id for Type " + t.name() + " and object " + o.toString() + ": '" + newId + "'"); } else { idSet.add(newId); } } count++; return newId; } public static void NOTremoveId(IdType t, Object o) { if (o == null) { return; } Set idSet = typeMap.get(t); long id = t.hashCode() + o.hashCode(); idSet.remove(id); } public static void NOTremoveId(IdType t, long id) { Set idSet = typeMap.get(t); idSet.remove(id); } }