protected <T> T readFromBody(VBox<T> vbox) { VBoxBody<T> body = vbox.body; if (body!= null && body.version > number) { body = newerVersionDetected(body); } addToReadSet(vbox); if (body == null) { /* * The object (vbox) is in the compact layout (of the AOM) and the * vbox itself corresponds to the most recent committed version. */ return (T) vbox; } else { return getValueFromBody(vbox, body); } }
@Override protected void finish() { super.finish(); for (VBox[] array : bodiesRead) { returnToPool(array); } // to allow garbage collecting the collections bodiesRead = null; arraysRead = null; boxesWritten = null; boxesWrittenInPlace = null; perTxValues = null; arrayWrites = null; arrayWritesCount = null; cleanUp(); }
@Override public <T> T getBoxValue(VBox<T> vbox) { /* * When either no one has written to this vbox or any committed writer * is not older than my version we know that this transaction (as well * as any parent) does not have a local value. In this case we read * directly from the vbox's body. */ OwnershipRecord currentOwner = vbox.inplace.orec; if (currentOwner.version > 0 && currentOwner.version <= this.number) { return readFromBody(vbox); } else { T value = getLocalValue(vbox); if (value == null) { // no local value exists return readFromBody(vbox); } // else return (value == NULL_VALUE) ? null : value; } }
protected <T> T getPerTxValue(PerTxBox<T> box) { T value = null; if (perTxValues != EMPTY_MAP) { value = (T) perTxValues.get(box); } if ((value == null) && (parent != null)) { value = getRWParent().getPerTxValue(box); } return value; }
protected <T> T getLocalValue(VBox<T> vbox) { InplaceWrite<T> inplace = vbox.inplace; if (inplace.orec.owner == this) { return inplace.tempValue; } T value = null; if (boxesWritten != EMPTY_MAP) { value = (T)boxesWritten.get(vbox); } if ((value == null) && (parent != null)) { value = getRWParent().getLocalValue(vbox); } return value; }
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 void tryCommit() { ReadWriteTransaction parent = getRWParent(); Cons<ParallelNestedTransaction> currentOrecs; Cons<ParallelNestedTransaction> modifiedOrecs; do { currentOrecs = parent.mergedTxs; modifiedOrecs = currentOrecs.cons(this); } while (!parent.CASmergedTxs(currentOrecs, modifiedOrecs)); if (!this.arraysRead.isEmpty()) { synchronized (parent) { // the possible array writes are already placed in the parent parent.arraysRead = this.arraysRead.reverseInto(parent.arraysRead); } } Transaction.current.set(null); }
@Override public <T> T getPerTxValue(PerTxBox<T> box, T initial) { T value = getPerTxValue(box); if (value == null) { value = initial; } return value; }
ReadWriteTransaction getRWParent() { return (ReadWriteTransaction) getParent(); }
@Override public <T> T getArrayValue(VArrayEntry<T> entry) { T value = getLocalArrayValue(entry); if (value == null) { value = entry.getValue(number); arraysRead = arraysRead.cons(entry); } return (value == NULL_VALUE) ? null : value; }
protected <T> void addToReadSet(VBox<T> vbox) { VBox[] readset = null; if (next < 0) { readset = borrowFromPool(); next = readset.length - 1; bodiesRead = bodiesRead.cons(readset); } else { readset = bodiesRead.first(); } readset[next--] = vbox; }
@Override protected void finish() { super.finish(); if (!context().inCommitAndBegin) { context().oldestRequiredVersion = null; } }
public void helpCommit() { ReadWriteTransaction parent = committer.getRWParent(); Cons<ParallelNestedTransaction> currentParentOrecs = parent.mergedTxs; if (currentParentOrecs == expectedParentOrecs) { committer.orec.nestedVersion = commitNumber; committer.orec.owner = parent; currentParentOrecs = currentParentOrecs.cons(committer); for (ParallelNestedTransaction childrenCommit : childrenToPropagate) { childrenCommit.orec.nestedVersion = commitNumber; childrenCommit.orec.owner = parent; currentParentOrecs = currentParentOrecs.cons(childrenCommit); } propagateVArraysFootprint(); parent.CASmergedTxs(expectedParentOrecs, currentParentOrecs); } }
@Override protected void tryCommit() { ReadWriteTransaction parent = getRWParent(); Cons<ParallelNestedTransaction> currentOrecs; Cons<ParallelNestedTransaction> modifiedOrecs; do { currentOrecs = parent.mergedTxs; modifiedOrecs = currentOrecs.cons(this); for (ParallelNestedTransaction child : mergedTxs) { modifiedOrecs = modifiedOrecs.cons(child); } } while (!parent.CASmergedTxs(currentOrecs, modifiedOrecs)); if (!this.arraysRead.isEmpty()) { synchronized (parent) { parent.arraysRead = this.arraysRead.reverseInto(parent.arraysRead); } } }