public void recoverValuesIfNeeded(Map<Long, DiskRecoveryStore> diskRecoveryStores) {
    // Early out if we start closing the parent.
    if (getParent().isClosing()) {
      return;
    }

    List<KRFEntry> sortedLiveEntries;

    HashMap<Long, DiskRegionInfo> targetRegions = new HashMap<>(regionMap.get());
    synchronized (diskRecoveryStores) {
      diskRecoveryStores.values()
          .removeIf(store -> isLruValueRecoveryDisabled(store) || store.lruLimitExceeded());
      // Get the a sorted list of live entries from the target regions
      targetRegions.keySet().retainAll(diskRecoveryStores.keySet());
    }

    sortedLiveEntries = getSortedLiveEntries(targetRegions.values());
    if (sortedLiveEntries == null) {
      // There are no live entries in this oplog to recover.
      return;
    }

    final ByteArrayDataInput in = new ByteArrayDataInput();
    for (KRFEntry entry : sortedLiveEntries) {
      // Early out if we start closing the parent.
      if (getParent().isClosing()) {
        return;
      }

      DiskEntry diskEntry = entry.getDiskEntry();
      DiskRegionView diskRegionView = entry.getDiskRegionView();
      long diskRegionId = diskRegionView.getId();

      // TODO DAN ok, here's what we need to do
      // 1) lock and obtain the correct RegionEntry that we are recovering too.
      // this will likely mean obtaining the correct DiskRecoveryStore, since
      // with
      // that we can find the region entry I believe.
      // 2) Make sure that the lru limit is not exceeded
      // 3) Update the region entry with the value from disk, assuming the value
      // from
      // disk is still valid. That is going to be something like

      synchronized (diskRecoveryStores) {
        DiskRecoveryStore diskRecoveryStore = diskRecoveryStores.get(diskRegionId);
        if (diskRecoveryStore == null) {
          continue;
        }

        // Reset the disk region view because it may have changed
        // due to the region being created.
        diskRegionView = diskRecoveryStore.getDiskRegionView();

        if (diskRegionView == null) {
          continue;
        }
        if (diskRecoveryStore.lruLimitExceeded()) {
          diskRecoveryStores.remove(diskRegionId);
          continue;
        }

        if (diskRegionView.isEntriesMapIncompatible()) {
          // Refetch the disk entry because it may have changed due to copying
          // an incompatible region map
          diskEntry = (DiskEntry) diskRecoveryStore.getRegionMap().getEntryInVM(diskEntry.getKey());
          if (diskEntry == null) {
            continue;
          }
        }

        synchronized (diskEntry) {
          // Make sure the entry hasn't been modified
          if (diskEntry.getDiskId() != null && diskEntry.getDiskId().getOplogId() == oplogId) {
            // dear lord, this goes through a lot of layers. Maybe we should
            // skip some?
            // * specifically, this could end up faulting in from a different
            // oplog, causing
            // us to seek.
            // * Also, there may be lock ordering issues here, Really, I guess I
            // want
            // a flavor of faultInValue that only faults in from this oplog.
            // * We could have some churn here, opening and closing this oplog
            // * We also might not be buffering adjacent entries? Not sure about
            // that one

            // * Ideally, this would fault the thing in only if it were in this
            // oplog and the lru limit wasn't hit
            // and it would return a status if the lru limit was hit to make us
            // remove the store.

            try {
              DiskEntry.Helper.recoverValue(diskEntry, getOplogId(), diskRecoveryStore, in);
            } catch (RegionDestroyedException ignore) {
              // This region has been destroyed, stop recovering from it.
              diskRecoveryStores.remove(diskRegionId);
            }
          }
        }
      }
    }
  }
This method is called by the async value recovery task to recover the values from the crf if
the keys were recovered from the krf.
geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java