package org.javers.core.graph; import org.javers.core.metamodel.object.Cdo; import org.javers.core.metamodel.object.InstanceId; import org.javers.core.metamodel.object.ValueObjectId; import java.util.*; /** * @author bartosz walacik */ class NodeReuser { private final Map<Object, ObjectNode> reverseCdoIdMap = new HashMap<>(); private final Set<ObjectNode> nodes = new HashSet<>(); private final Queue<ObjectNode> stubs = new LinkedList<>(); private int reusedNodes; private int entities; private int valueObjects; NodeReuser() { } boolean isReusable(Cdo cdo) { return reverseCdoIdMap.containsKey(reverseCdoIdMapKey(cdo)); } ObjectNode getForReuse(Cdo cdo) { reusedNodes++; return reverseCdoIdMap.get(reverseCdoIdMapKey(cdo)); } Set<ObjectNode> nodes() { return nodes; } void saveForReuse(ObjectNode reference) { if (reference.getGlobalId() instanceof InstanceId) { entities++; } if (reference.getGlobalId() instanceof ValueObjectId) { valueObjects++; } reverseCdoIdMap.put(reverseCdoIdMapKey(reference.getCdo()), reference); nodes.add(reference); } void enqueueStub(ObjectNode nodeStub) { stubs.offer(nodeStub); } ObjectNode pollStub(){ return stubs.poll(); } boolean hasMoreStubs(){ return !stubs.isEmpty(); } int nodesCount() { return reverseCdoIdMap.size(); } int reusedNodesCount() { return reusedNodes; } int entitiesCount() { return entities; } int voCount() { return valueObjects; } /** * InstanceId for Entities, * System.identityHashCode for ValueObjects */ private Object reverseCdoIdMapKey(Cdo cdo) { if (cdo.getGlobalId() instanceof InstanceId) { return cdo.getGlobalId(); } return System.identityHashCode(cdo.getWrappedCdo().get()); } }