private void processNewUndelete(ScanResults results, StoreKey key, IndexValue undeleteValue,
      IndexValue originalPutValue, IndexValue previousValue) {
    // First deal with container bucket
    if (!previousValue.isDelete()) {
      // This previous value is not DELETE, current UNDELETE would not change container bucket.
      // There are several possibility when the previous value is not DELETE.
      // 1. PUT UNDELETE: UNDELETE doesn't change any bucket
      // 2. PUT TTL_UPDATE UNDELETE: UNDELETE doesn't change any bucket
      // 3. PUT DELETE UNDELETE UNDELETE: the last UNDELETE doesn't change any bucket
      // UNDELETE would resurrect a deleted IndexValue, if the previous value is not DELETE, then the IndexValue doesn't
      // need to be resurrected.
    } else {
      handleContainerBucketUpdate(results, originalPutValue, undeleteValue.getOperationTimeInMs(), ADD);
      handleContainerBucketUpdate(results, originalPutValue, originalPutValue.getExpiresAtMs(), SUBTRACT);
    }

    // Now deal with log segment bucket
    // Current UNDELETE is always valid
    results.updateLogSegmentBaseBucket(undeleteValue.getOffset().getName(), undeleteValue.getSize());
    if (previousValue.isDelete()) {
      // Previous IndexValue is a DELETE, it will be invalidated by current DELETE. So we have to revert the previous
      // DELETE here as if it doesn't exist. After reverting changes made by previous DELETE, we will process the current
      // DELETE IndexValue.
      processDeleteUpdateLogSegmentHelper(results, key, previousValue, originalPutValue, SUBTRACT);
    } else if (previousValue.isUndelete()) {
      // Previous IndexValue is an UNDELETE, it should already
      // 1. Added it's size to the base bucket of the scan result
      // we need to recover from this operation
      results.updateLogSegmentBaseBucket(previousValue.getOffset().getName(), SUBTRACT * previousValue.getSize());
    }
  }
Helper function to process new UNDELETE entries and make appropriate updates to the given {@link ScanResults}.
@param results the {@link ScanResults} to apply the updates to
@param key the {@link StoreKey} of the new UNDELETE
@param undeleteValue the {@link IndexValue} of the new UNDELETE
@param originalPutValue the {@link IndexValue} of the original PUT
@param previousValue the {@link IndexValue} comes prior to the new UNDELETE
ambry-store/src/main/java/com/github/ambry/store/BlobStoreStats.java