protected <T> T getLocalArrayValue(VArrayEntry<T> entry) { T value = null; if (arrayWrites != EMPTY_MAP) { VArrayEntry<T> wsEntry = (VArrayEntry<T>) arrayWrites.get(entry); if (wsEntry != null) { value = (wsEntry.getWriteValue() == null ? (T) NULL_VALUE : wsEntry.getWriteValue()); } } if ((value == null) && (parent != null)) { value = getRWParent().getLocalArrayValue(entry); } return value; }
@Override protected <T> T getLocalArrayValue(VArrayEntry<T> entry) { ReadWriteTransaction iter = getRWParent(); while (iter != null) { synchronized (iter) { if (iter.arrayWrites != EMPTY_MAP) { VArrayEntry<T> wsEntry = (VArrayEntry<T>) iter.arrayWrites.get(entry); if (wsEntry != null) { return (wsEntry.getWriteValue() == null ? (T) NULL_VALUE : wsEntry.getWriteValue()); } } } iter = iter.getRWParent(); } return null; }
@Override protected <T> T getLocalArrayValue(VArrayEntry<T> entry) { ReadWriteTransaction iter = getRWParent(); while (iter != null) { if (iter.arrayWrites != EMPTY_MAP) { VArrayEntry<T> wsEntry = (VArrayEntry<T>) iter.arrayWrites.get(entry); if (wsEntry == null) { iter = iter.getRWParent(); continue; } if (wsEntry.nestedVersion <= retrieveAncestorVersion(iter)) { return (wsEntry.getWriteValue() == null ? (T) NULL_VALUE : wsEntry.getWriteValue()); } } iter = iter.getRWParent(); } return null; }
@SuppressWarnings("unchecked") public GarbageCollectable commit(int txNumber, VArrayEntry[] writesToCommit, int[] logEntryIndexes) { // Prepare arrays for log E[] logEntryValues = (E[]) new Object[writesToCommit.length]; // Create and place log node log = new VArrayLogNode<E>(logEntryIndexes, logEntryValues, txNumber - 1, log); // Bump array version version = txNumber; // Proceed with normal writeback and populating log values int i = 0; for (VArrayEntry<E> entry : writesToCommit) { // Read old value from the array, and copy it to the log E oldValue = values.get(entry.index); if (oldValue == null) oldValue = (E) NULL_VALUE; logEntryValues[i++] = oldValue; // Write the new value // Using a lazySet because we don't need the new value to be seen by other threads // as soon as possible. In fact, it would be nice if only threads with transactions // created after we finish our commit see the new value. // For more details see the java.util.concurrent.atomic package description javadoc. values.lazySet(entry.index, entry.getWriteValue()); // Volatile write! } return log; } }
@Override protected <T> T getLocalArrayValue(VArrayEntry<T> entry) { if (this.arrayWrites != EMPTY_MAP) { VArrayEntry<T> wsEntry = (VArrayEntry<T>) this.arrayWrites.get(entry); if (wsEntry != null) { return (wsEntry.getWriteValue() == null ? (T) NULL_VALUE : wsEntry.getWriteValue()); } } ReadWriteTransaction iter = getRWParent(); while (iter != null) { synchronized (iter) { if (iter.arrayWrites != EMPTY_MAP) { VArrayEntry<T> wsEntry = (VArrayEntry<T>) iter.arrayWrites.get(entry); if (wsEntry == null) { iter = iter.getRWParent(); continue; } if (wsEntry.nestedVersion <= retrieveAncestorVersion(iter)) { this.arraysRead = this.arraysRead.cons(entry); entry.setReadOwner(iter); return (wsEntry.getWriteValue() == null ? (T) NULL_VALUE : wsEntry.getWriteValue()); } else { TransactionSignaller.SIGNALLER.signalCommitFail(iter); } } } iter = iter.getRWParent(); } return null; }