private void moveStarts ( SSTableReader newReader , DecoratedKey lowerbound , boolean reset ) { if ( isOffline ) return ; List < SSTableReader > toReplace = new ArrayList <> ( ) ; List < SSTableReader > replaceWith = new ArrayList <> ( ) ; final List < DecoratedKey > invalidateKeys = new ArrayList <> ( ) ; if ( ! reset ) { invalidateKeys . addAll ( cachedKeys . keySet ( ) ) ; for ( Map . Entry < DecoratedKey , RowIndexEntry > cacheKey : cachedKeys . entrySet ( ) ) newReader . cacheKey ( cacheKey . getKey ( ) , cacheKey . getValue ( ) ) ; } cachedKeys = new HashMap <> ( ) ; for ( SSTableReader sstable : ImmutableList . copyOf ( rewriting ) ) { // we call getCurrentReplacement() to support multiple rewriters operating over the same source readers at once. // note: only one such writer should be written to at any moment final SSTableReader latest = sstable . getCurrentReplacement ( ) ; SSTableReader replacement ; if ( reset ) { DecoratedKey newStart = originalStarts . get ( sstable . descriptor ) ; replacement = latest . cloneWithNewStart ( newStart , null ) ; } else { // skip any sstables that we know to already be shadowed if ( latest . openReason == SSTableReader . OpenReason . SHADOWED ) continue ; if ( latest . first . compareTo ( lowerbound ) > 0 ) continue ; final Runnable runOnClose = new Runnable ( ) { public void run ( ) { // this is somewhat racey, in that we could theoretically be closing this old reader // when an even older reader is still in use, but it's not likely to have any major impact for ( DecoratedKey key : invalidateKeys ) latest . invalidateCacheKey ( key ) ; } } ; if ( lowerbound . compareTo ( latest . last ) >= 0 ) { replacement = latest . cloneAsShadowed ( runOnClose ) ; } else { DecoratedKey newStart = latest . firstKeyBeyond ( lowerbound ) ; assert newStart != null ; replacement = latest . cloneWithNewStart ( newStart , runOnClose ) ; } } toReplace . add ( latest ) ; replaceWith . add ( replacement ) ; rewriting . remove ( sstable ) ; rewriting . add ( replacement ) ; } cfs . getDataTracker ( ) . replaceWithNewInstances ( toReplace , replaceWith ) ; }
Replace the readers we are rewriting with cloneWithNewStart reclaiming any page cache that is no longer needed and transferring any key cache entries over to the new reader expiring them from the old . if reset is true we are instead restoring the starts of the readers from before the rewriting began