@Override public <T> T getBoxValue(VBox<T> vbox) { numBoxReads++; VBoxBody<T> body = vbox.getBody(number); if (body.value == VBox.NOT_LOADED_VALUE) { vbox.reload(); // after the reload, the (new) body should have the required loaded value // if not, then something went wrong and it's better to abort // body = vbox.body.getBody(number); body = vbox.getBody(number); if (body.value == VBox.NOT_LOADED_VALUE) { logger.error("Couldn't load the VBox: {}", vbox.getId()); throw new VersionNotAvailableException(); } } return body.value; }
public VBoxBody<E> getOldestValidBody() { if (isBodyNullOrVersion0NotLoaded(this.body)) { return null; } else { VBoxBody<E> oldest = this.body; while (isBodyNullOrVersion0NotLoaded(oldest.next)) { oldest = oldest.next; } return oldest; } }
public final VBoxBody<E> getBody(int maxVersion) { // logger.debug("looking up {} for version {}", this.getId(), maxVersion); VBoxBody<E> current = body; while (current != null && current.version > maxVersion) { current = current.next; } if (current == null) { // logger.debug("Returning NOT_LOADED_BODY due to null."); return notLoadedBody(); // VBox.NOT_LOADED_VALUE; } // logger.debug("In VBox {}, found version {} with '{}'", this.getId(), current.version, current.value); return current; }
public void putNotLoadedValue() { this.put(VBox.<E> notLoadedValue()); }
@Override public synchronized VBoxBody addNewVersion(int txNumber) { if (body.version < txNumber) { return commit(VBox.<E> notLoadedValue(), txNumber); } else { /* when adding a version to the vbox it may happen that such version already exists. That can happen if the box gets reloaded before the remote commit is applied, but after such remote commit data is already persisted. In that case, just return null, because we are not responsible for what will happen to that vboxbody */ logger.debug("tried to add an older version for a box: id=" + getId() + " -> " + body.version + " is not < " + txNumber); return null; } }
private static String makeKeyFor(VBox vbox) { return vbox.getId(); }
boolean reload(int requiredVersion) { if (logger.isDebugEnabled()) { logger.debug("Reload VBox {} for version {}", this.getId(), requiredVersion); } try { //Re-test to see whether some other thread already did the job for us. //This also requires the body's value slot to be final. //VBoxBody<E> body = this.body.getBody(Transaction.current().getNumber()); VBoxBody<E> body = getBody(requiredVersion); if (body.value == VBox.NOT_LOADED_VALUE) { if (body.version == 0) { doReload(); } else { reloadBody(body); } } return true; } catch (Throwable e) { // what to do? logger.warn("Couldn't reload vbox {}. Throwable:{}. Message:{}", getId(), e.getClass(), e.getMessage()); //e.printStackTrace(); return false; } }
logger.debug("No such key: {}", key); if (versionToLoad == 0) { throw new PersistenceException("Version of vbox " + box.getId() + " not found for transaction number " + txNumber); VBoxBody bodies = VBox.notLoadedBody(); bodies = VBox.makeNewBody(pair.first.getData(), pair.second, bodies);
@Override protected Cons<GarbageCollectable> writeBackLoop(int newTxNumber, int min, int max, jvstm.VBox[] vboxes, Object[] values) { Object newValue = VBox.notLoadedValue(); Cons<GarbageCollectable> newBodies = Cons.empty(); for (int i = max - 1; i >= min; i--) { jvstm.VBox vbox = vboxes[i]; logger.debug("Will commit to vbox {} version {} with value {}", ((VBox) vbox).getId(), newTxNumber, newValue); VBoxBody newBody = vbox.commit(newValue, newTxNumber); newBodies = newBodies.cons(newBody); } return newBodies; }
@Override public void reloadAttribute(VBox box) { int txNumber = jvstm.Transaction.current().getNumber(); boolean success = false; VBoxBody oldestValidBody = box.getOldestValidBody(); int highestVersionToLoad; if (oldestValidBody == null) { highestVersionToLoad = Transaction.mostRecentCommittedRecord.transactionNumber; } else { highestVersionToLoad = oldestValidBody.version - 1; } if (txNumber > highestVersionToLoad) { logger.debug("Version {} for vbox {} is already loaded", txNumber, box.getId()); return; } logger.debug("Will load versions [{};{}] for vbox {}", highestVersionToLoad, txNumber, box.getId()); VBoxBody tail = loadVersionsInRange(box, highestVersionToLoad, txNumber); replaceTail(box, oldestValidBody, tail); }
/*synchronized */boolean reload() { return reload(Transaction.current().getNumber()); }
public static <T> boolean isBodyNullOrVersion0NotLoaded(VBoxBody<T> body) { return (body == null || (body.version == 0 && body.value == notLoadedValue())); }
@Override public void reloadAttribute(VBox box) { int txNumber = jvstm.Transaction.current().getNumber(); List<VersionedValue> vvalues = getMostRecentVersions(box, txNumber); box.mergeVersions(vvalues); }
private VBoxBody<E> convertVersionedValuesToVBoxBodies(List<VersionedValue> vvalues) { ListIterator<VersionedValue> iter = vvalues.listIterator(vvalues.size()); VBoxBody<E> result = null; while (iter.hasPrevious()) { VersionedValue vvalue = iter.previous(); result = VBox.makeNewBody((E) vvalue.getValue(), vvalue.getVersion(), result); } return result; }
protected void synchronizeJvstmState(int serverId) { ActiveTransactionsRecord activeRecord = Transaction.getRecordForNewTransaction(); Transaction tx = new InitTransaction(activeRecord); tx.start(); VBox<Integer> initBox = StandaloneVBox.makeNew("SERVER" + serverId, false); initBox.put(serverId); tx.commitTx(true); logger.info("Set the last committed TX number to {}", Transaction.mostRecentCommittedRecord.transactionNumber); }
private String makeKeyFor(VBox vbox) { return vbox.getId(); }
vbox.reload(lastSeenCommittedTxNumber);
protected void replaceBodyValue(VBoxBody body, Object value) { if (UNSAFE.compareAndSwapObject(body, bodyValueOffset, VBox.notLoadedValue(), value)) { logger.debug("Set value for body in version {}", body.version); } else { logger.debug("Value for body in version {} was already set", body.version); } }
@Override public void reloadAttribute(VBox box) { int txNumber = jvstm.Transaction.current().getNumber(); List<VersionedValue> vvalues = getMostRecentVersions(box, txNumber); box.mergeVersions(vvalues); }
@Override public <T> T getBoxValue(VBox<T> vbox) { numBoxReads++; VBoxBody<T> body = vbox.getBody(number); if (body.value == VBox.NOT_LOADED_VALUE) { vbox.reload(); // after the reload, the (new) body should have the required loaded value // if not, then something went wrong and it's better to abort // body = vbox.body.getBody(number); body = vbox.getBody(number); if (body.value == VBox.NOT_LOADED_VALUE) { logger.error("Couldn't load the VBox: {}", vbox.getId()); throw new VersionNotAvailableException(); } } return body.value; }