private static ActiveTransactionsRecord findActiveRecordForNumber(ActiveTransactionsRecord rec, int number) { while (rec.transactionNumber < number) { rec = rec.getNext(); } return rec; }
protected ActiveTransactionsRecord findLatestRecord(ActiveTransactionsRecord from) { ActiveTransactionsRecord latest = from; for (ActiveTransactionsRecord aux; (aux = latest.getNext()) != null; latest = aux) { ; } return latest; }
private static ActiveTransactionsRecord findActiveRecordForNumber(ActiveTransactionsRecord rec, int number) { while (rec.transactionNumber < number) { rec = rec.getNext(); } return rec; }
protected ActiveTransactionsRecord helpCommitAll() { ActiveTransactionsRecord lastSeenCommitted = Transaction.mostRecentCommittedRecord; ActiveTransactionsRecord recordToCommit = lastSeenCommitted.getNext(); while (recordToCommit != null) { helpCommit(recordToCommit); lastSeenCommitted = recordToCommit; recordToCommit = recordToCommit.getNext(); } return lastSeenCommitted; }
public static ActiveTransactionsRecord getRecordForNewTransaction() { ActiveTransactionsRecord rec = Transaction.mostRecentCommittedRecord; TxContext ctx = threadTxContext.get(); ctx.oldestRequiredVersion = rec; // volatile write while (true) { while ((rec.getNext() != null) && (rec.getNext().isCommitted())) { rec = rec.getNext(); } if (rec != ctx.oldestRequiredVersion) { // a more recent record exists, so backoff and try again with the new one ctx.oldestRequiredVersion = rec; // volatile write } else { return rec; } } }
private void cleanUnusedRecords(ActiveTransactionsRecord upToThisRecord) { // int diff = (upToThisRecord.transactionNumber - this.lastCleanedRecord.transactionNumber); // total += diff; // if (diff != 0) count++; // if (diff > max) max = diff; while (this.lastCleanedRecord.transactionNumber < upToThisRecord.transactionNumber) { ActiveTransactionsRecord toClean = this.lastCleanedRecord.getNext(); this.lastCleanedRecord = toClean; cleanersPool.execute(new CleanTask(toClean)); } }
protected void ensureCommitStatus() { ActiveTransactionsRecord recordToCommit = Transaction.mostRecentCommittedRecord.getNext(); while ((recordToCommit != null) && (recordToCommit.transactionNumber <= getCommitTxRecord().transactionNumber)) { helpCommit(recordToCommit); recordToCommit = recordToCommit.getNext(); } }
@Override protected void ensureCommitStatus() { ActiveTransactionsRecord recordToCommit = Transaction.mostRecentCommittedRecord.getNext(); while ((recordToCommit != null) && (recordToCommit.transactionNumber < getCommitTxRecord().transactionNumber)) { helpCommit(recordToCommit); recordToCommit = recordToCommit.getNext(); } }
public void run() { while (this.lastCleaned.transactionNumber < upToThis.transactionNumber) { this.lastCleaned = this.lastCleaned.getNext(); this.lastCleaned.clean(); } } }
/** * Validates this read-set against all active transaction records more recent that the one * <code>lastChecked</code>. * * @return The last successfully validated ActiveTransactionsRecord * @throws CommitException if the validation fails */ protected ActiveTransactionsRecord validate(ActiveTransactionsRecord startCheck) { ActiveTransactionsRecord lastChecked = startCheck; ActiveTransactionsRecord recordToCheck = lastChecked.getNext(); while (recordToCheck != null) { lastChecked = recordToCheck; recordToCheck = recordToCheck.getNext(); } if (lastChecked != startCheck) { helpCommitAll(); snapshotValidation(lastChecked.transactionNumber); } return lastChecked; }
private ActiveTransactionsRecord findOldestRecordInUse() { // We use this in case there are no thread running, to know until where to clean. If we // only read this after doing the search we might clean more than we should, because a new // transaction can begin and commit a new record at any time. By reading first, we ensure // that if all threads have gone, we can clean at least until here. ActiveTransactionsRecord mostRecentCommittedAtBegin = Transaction.mostRecentCommittedRecord; for (ActiveTransactionsRecord next = mostRecentCommittedAtBegin.getNext(); (next != null) && next.isCommitted(); next = next.getNext()) { mostRecentCommittedAtBegin = next; } // we could use this opportunity to advance Transaction.mostRecentCommittedRecord // First pass. Here we check all contexts to identify the oldest record in use. ActiveTransactionsRecord minRequiredRecord1 = findOldestRecordUpTo(null, Integer.MAX_VALUE); // If there was no record identified as a minimum we can safely clean up to the record that // was committed at the beginning, because all other threads will see it and use it (or use // another more recent record which is ok) if (minRequiredRecord1 == null) { return mostRecentCommittedAtBegin; } // Otherwise we do a second pass. In the second pass we re-check all the records that were // checked before the identified oldest context, as they may have changed concurrently to a // lower minimum. ActiveTransactionsRecord minRequiredRecord2 = findOldestRecordUpTo(this.oldestContext, minRequiredRecord1.transactionNumber); // If we find another record in the second pass then that is the minimum. If not then the // first found is it. return (minRequiredRecord2 != null) ? minRequiredRecord2 : minRequiredRecord1; }
protected boolean isSnapshotValidationWorthIt(ActiveTransactionsRecord lastRecord) { if (this.bodiesRead.isEmpty()) { return false; } int numberOfReadsToCheck = this.bodiesRead.first().length - (next + 1); // if there are more arrays the rest are full, for sure for (VBox[] array : bodiesRead.rest()) { numberOfReadsToCheck += array.length; } int numberOfWritesToCheck = 0; for (ActiveTransactionsRecord rec = this.activeTxRecord.getNext(); rec != null; rec = rec.getNext()) { numberOfWritesToCheck += rec.getWriteSet().size(); } return ((float) numberOfWritesToCheck) / numberOfReadsToCheck > WR_THRESHOLD; }