diff --git a/core/src/main/java/com/orientechnologies/orient/core/tx/OTransactionIndexChangesPerKey.java b/core/src/main/java/com/orientechnologies/orient/core/tx/OTransactionIndexChangesPerKey.java index 4e90793ea34..f591257da87 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/tx/OTransactionIndexChangesPerKey.java +++ b/core/src/main/java/com/orientechnologies/orient/core/tx/OTransactionIndexChangesPerKey.java @@ -35,8 +35,7 @@ public class OTransactionIndexChangesPerKey { /* internal */ static final int SET_ADD_THRESHOLD = 8; public final Object key; - private final Map ridToNEntries; - private final List entries; + private final OTxIndexChangesList entries; public boolean clientTrackOnly; @@ -79,43 +78,35 @@ public OIdentifiable getValue() { public void setValue(OIdentifiable newValue) { ORID oldValueId = value == null ? null : value.getIdentity(); - Integer oldCount = ridToNEntries.get(oldValueId); - ridToNEntries.put(oldValueId, oldCount == null || oldCount < 1 ? 0 : oldCount - 1); - ORID newValueId = newValue == null ? null : newValue.getIdentity(); - Integer newCount = ridToNEntries.get(newValueId); - ridToNEntries.put(newValueId, newCount == null ? 1 : newCount + 1); + Optional node = entries.getNode(this); this.value = newValue; + node.ifPresent(x -> x.onRidChange(oldValueId, newValueId)); } } public OTransactionIndexChangesPerKey(final Object iKey) { this.key = iKey; - entries = new ArrayList(); - ridToNEntries = new HashMap<>(); + entries = new OTxIndexChangesList(); } public void add(OIdentifiable iValue, final OPERATION iOperation) { synchronized (this) { ORID valueIdentity = iValue == null ? null : iValue.getIdentity(); Iterator iter = entries.iterator(); - Integer count = ridToNEntries.get(valueIdentity); - if (count != null && count > 0) { - while (iter.hasNext()) { - OTransactionIndexEntry entry = iter.next(); - if (((entry.value == iValue) || (entry.value != null && entry.value.equals(iValue))) - && !entry.operation.equals(iOperation)) { - iter.remove(); - ridToNEntries.put(valueIdentity, count - 1); - return; - } - } + + Optional nodeToRemove = + entries.getFirstNode( + valueIdentity, iOperation == OPERATION.PUT ? OPERATION.REMOVE : OPERATION.PUT); + if (nodeToRemove.isPresent()) { + nodeToRemove.get().remove(); + return; } + OTransactionIndexEntry item = new OTransactionIndexEntry(valueIdentity, iOperation); entries.add(item); - ridToNEntries.put(valueIdentity, count == null ? 1 : count + 1); } } @@ -143,7 +134,6 @@ public Iterable interpret(Interpretation interpretation) public void clear() { synchronized (this) { this.entries.clear(); - this.ridToNEntries.clear(); } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/tx/OTxIndexChangesList.java b/core/src/main/java/com/orientechnologies/orient/core/tx/OTxIndexChangesList.java index d49b0b9edca..c9ece58f957 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/tx/OTxIndexChangesList.java +++ b/core/src/main/java/com/orientechnologies/orient/core/tx/OTxIndexChangesList.java @@ -46,6 +46,16 @@ public void remove() { // update size size--; } + + public void onRidChange(ORID oldRid, ORID newRid) { + ridToNodes.get(oldRid).remove(this); + List newMapList = ridToNodes.get(newRid); + if (newMapList == null) { + newMapList = new ArrayList<>(); + ridToNodes.put(newRid, newMapList); + } + newMapList.add(this); + } } private Node first; @@ -417,4 +427,21 @@ public List subList( // TODO implement this throw new UnsupportedOperationException(); } + + public Optional getFirstNode(ORID rid, OTransactionIndexChanges.OPERATION op) { + List list = ridToNodes.get(rid); + if (list != null) { + return list.stream().filter(x -> x.entry.getOperation() == op).findFirst(); + } + return Optional.empty(); + } + + public Optional getNode(OTransactionIndexChangesPerKey.OTransactionIndexEntry entry) { + ORID rid = entry.getValue() == null ? null : entry.getValue().getIdentity(); + List list = ridToNodes.get(rid); + if (list != null) { + return list.stream().filter(x -> x.entry == entry).findFirst(); + } + return Optional.empty(); + } }