private Throwable checkpoint(Throwable accumulate) { if (logger.isDebugEnabled()) logger.debug("Checkpointing update:{}, obsolete:{}", staged.update, staged.obsolete); if (staged.isEmpty()) return accumulate; Set<SSTableReader> toUpdate = toUpdate(); Set<SSTableReader> fresh = copyOf(fresh()); // check the current versions of the readers we're replacing haven't somehow been replaced by // someone else checkNotReplaced(filterIn(toUpdate, staged.update)); // ensure any new readers are in the compacting set, since we aren't done with them yet // and don't want anyone else messing with them // apply atomically along with updating the live set of readers tracker.apply( compose(updateCompacting(emptySet(), fresh), updateLiveSet(toUpdate, staged.update))); // log the staged changes and our newly marked readers marked.addAll(fresh); logged.log(staged); // setup our tracker, and mark our prior versions replaced, also releasing our references to // them // we do not replace/release obsoleted readers, since we may need to restore them on rollback accumulate = setReplaced(filterOut(toUpdate, staged.obsolete), accumulate); accumulate = release(selfRefs(filterOut(toUpdate, staged.obsolete)), accumulate); staged.clear(); return accumulate; }
/** construct a Transaction for use in an offline operation */ public static LifecycleTransaction offline( OperationType operationType, Iterable<SSTableReader> readers) { // if offline, for simplicity we just use a dummy tracker Tracker dummy = new Tracker(null, false); dummy.addInitialSSTables(readers); dummy.apply(updateCompacting(emptySet(), readers)); return new LifecycleTransaction(dummy, operationType, readers); }
private Throwable unmarkCompacting(Set<SSTableReader> unmark, Throwable accumulate) { accumulate = tracker.apply(updateCompacting(unmark, emptySet()), accumulate); // when the CFS is invalidated, it will call unreferenceSSTables(). However, // unreferenceSSTables only deals // with sstables that aren't currently being compacted. If there are ongoing compactions that // finish or are // interrupted after the CFS is invalidated, those sstables need to be unreferenced as well, so // we do that here. accumulate = tracker.dropSSTablesIfInvalid(accumulate); return accumulate; }
/** undo all of the changes made by this transaction, resetting the state to its original form */ public Throwable doAbort(Throwable accumulate) { if (logger.isDebugEnabled()) logger.debug( "Aborting transaction over {}, with ({},{}) logged and ({},{}) staged", originals, logged.update, logged.obsolete, staged.update, staged.obsolete); if (logged.isEmpty() && staged.isEmpty()) return accumulate; // mark obsolete all readers that are not versions of those present in the original set Iterable<SSTableReader> obsolete = filterOut(concatUniq(staged.update, logged.update), originals); logger.debug("Obsoleting {}", obsolete); // we don't pass the tracker in for the obsoletion, since these readers have never been notified // externally // nor had their size accounting affected accumulate = markObsolete(null, obsolete, accumulate); // replace all updated readers with a version restored to its original state accumulate = tracker.apply(updateLiveSet(logged.update, restoreUpdatedOriginals()), accumulate); // setReplaced immediately preceding versions that have not been obsoleted accumulate = setReplaced(logged.update, accumulate); // we have replaced all of logged.update and never made visible staged.update, // and the files we have logged as obsolete we clone fresh versions of, so they are no longer // needed either // any _staged_ obsoletes should either be in staged.update already, and dealt with there, // or is still in its original form (so left as is); in either case no extra action is needed accumulate = release(selfRefs(concat(staged.update, logged.update, logged.obsolete)), accumulate); logged.clear(); staged.clear(); return accumulate; }