docs: protected int removeExpiredCache(boolean scan) {
          final String methodName = "removeExpiredCache()";
          int returnCode = NO_EXCEPTION;
          if (object_cache == null) {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, methodName, "The disk object cache is null for cacheName=" + this.cacheName);
              return returnCode;
          }
          long start = System.nanoTime();
          long tPopulateDepTablesTime = 0;
          long tReadRangeTime = 0;
          long tDeleteTime = 0;
          long tScanExpiredCount = 0;
          long tExplicitDeleted = 0;
          long tScanDeleted = 0;
          long tGCDeleted = 0;
          long tDeletedSize = 0;
          long t;
          if (!scan) {
              int totalSize = this.invalidationBuffer.size() + this.invalidationBuffer.size(HTODInvalidationBuffer.GC_BUFFER);
              if (totalSize == 0) { // invalidationBuffer empty?
                  return returnCode;
              }
          }
          if (getCacheIdsSize() > 0) {
              StringBuffer dcmsg = new StringBuffer();
              dcmsg.append("  DiskCacheSize=");
              dcmsg.append(getCacheIdsSize());
              dcmsg.append("  DepIdsSize=");
              dcmsg.append(getDepIdsSize());
              dcmsg.append("  TemplatesSize=");
              dcmsg.append(getTemplatesSize());
              if (this.cod.enableCacheSizeInBytes) {
                  dcmsg.append("  CacheSizeInBytes=");
                  dcmsg.append(this.cod.currentCacheSizeInBytes);
              }
              dcmsg.append("  Scan=");
              dcmsg.append(scan);
              dcmsg.append("  ExplicitBuffer=");
              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.EXPLICIT_BUFFER));
              dcmsg.append("  ScanBuffer=");
              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.SCAN_BUFFER));
              dcmsg.append("  GCBuffer=");
              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.GC_BUFFER));
              if (scan) {
                  Tr.info(tc, "DYNA0057I", new Object[] { this.cacheName, dcmsg.toString() });
              } else if (!scan && tc.isEventEnabled()) {
                  Tr.event(tc, "The disk cache cleanup started for the cache name \"" + this.cacheName + "\"." + "The statistics are: " + dcmsg.toString());
              } else {
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, methodName, "The disk cache cleanup started for cache name \"" + this.cacheName + "\"." + " The statistics are: " + dcmsg.toString());
              }
              if (this.cod.populateDependencyTable) {
                  cacheIdsTable = new HashMap(getCacheIdsSize());
                  this.cod.populateDependencyTable = false;
                  t = System.nanoTime();
                  if (!this.disableDependencyId) {
                      returnCode = populateAuxDependencyTable(DEP_ID_DATA, cacheIdsTable, this.cod.delayOffloadDepIdBuckets, cod.delayOffloadEntriesLimit);
                      if (returnCode == DISK_EXCEPTION) {
                          cacheIdsTable.clear();
                          cacheIdsTable = null;
                          return returnCode;
                      }
                  }
                  if (!this.disableTemplatesSupport) {
                      returnCode = populateAuxDependencyTable(TEMPLATE_ID_DATA, cacheIdsTable, this.cod.delayOffloadTemplateBuckets, cod.delayOffloadEntriesLimit);
                      if (returnCode == DISK_EXCEPTION) {
                          cacheIdsTable.clear();
                          cacheIdsTable = null;
                          return returnCode;
                      }
                  }
                  tPopulateDepTablesTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t);
              }
  
              int i = 0;
              boolean complete = false;
              ValueSet expiredIds = new ValueSet(NUM_SCAN);
              long lastTimeToDisplay = System.nanoTime();
              boolean firstScan = true;
              do {
                  int scanExpiredCount = 0;
                  this.scanExpiredTime = 0;
                  if (scan && (this.invalidationBuffer.size() < this.cod.invalidationBufferSize)) {
                      if (this.invalidationBuffer.isLoopOnce()) {
                          break;
                      }
                      if (this.cod.evictionPolicy != CacheConfig.EVICTION_NONE &&
                          this.cod.diskCachePerformanceLevel != CacheConfig.HIGH &&
                          this.EvictionTable.size() > 0) {
                          ArrayList alist = getExpiredEntriesFromEvictionTable();
                          tScanExpiredCount += alist.size();
                          this.invalidationBuffer.add(alist, HTODInvalidationBuffer.GC_BUFFER);
                          if (tc.isDebugEnabled() || tc.isEventEnabled()) {
                              lastTimeToDisplay = System.nanoTime();
                              dcmsg.setLength(0);
                              dcmsg.append(methodName);
                              dcmsg.append(":scanGC ++++ cacheName=");
                              dcmsg.append(this.cacheName);
                              dcmsg.append(" DiskCacheSize=");
                              dcmsg.append(getCacheIdsSize());
                              if (this.cod.enableCacheSizeInBytes) {
                                  dcmsg.append("  CacheSizeInBytes=");
                                  dcmsg.append(this.cod.currentCacheSizeInBytes);
                              }
                              dcmsg.append(" ScanExpiredEntries=");
                              dcmsg.append(tScanExpiredCount);
                              dcmsg.append(" ExplicitEntriesDeleted=");
                              dcmsg.append(tExplicitDeleted);
                              dcmsg.append(" ScanEntriesDeleted=");
                              dcmsg.append(tScanDeleted);
                              dcmsg.append(" GCEntriesDeleted=");
                              dcmsg.append(tGCDeleted);
                              dcmsg.append(" DeletedSize=");
                              dcmsg.append(tDeletedSize);
                              dcmsg.append(" ExplicitBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.EXPLICIT_BUFFER));
                              dcmsg.append(" ScanBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.SCAN_BUFFER));
                              dcmsg.append(" GCBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.GC_BUFFER));
                              dcmsg.append(" CleanupScanPending=");
                              dcmsg.append(this.invalidationBuffer.isCleanupPending());
  
                              if (tc.isDebugEnabled()) {
                                  Tr.debug(tc, dcmsg.toString());
                              } else {
                                  Tr.event(tc, dcmsg.toString());
                              }
                          }
                          complete = true;
                      } else {
                          if (firstScan) {
                              i = 0;
                              firstScan = false;
                          }
                          Result result = readExpiredByRange(expiredIds, i, NUM_SCAN);
                          returnCode = result.returnCode;
                          if (returnCode == DISK_EXCEPTION) {
                              break;
                          }
                          complete = result.bComplete;
                          tReadRangeTime = tReadRangeTime + this.scanExpiredTime;
                          scanExpiredCount = expiredIds.size();
                          if (scanExpiredCount > 0) {
                              this.invalidationBuffer.add(expiredIds, HTODInvalidationBuffer.SCAN_BUFFER, CachePerf.TIMEOUT, CachePerf.LOCAL,
                                                          !Cache.FROM_DEPID_TEMPLATE_INVALIDATION, HTODInvalidationBuffer.FIRE_EVENT, !HTODInvalidationBuffer.CHECK_FULL);
                              expiredIds.clear();
                          }
                          tScanExpiredCount += scanExpiredCount;
                          if (tc.isEventEnabled() && (System.nanoTime() - lastTimeToDisplay) >= TimeUnit.SECONDS.toNanos(10)) {
                              lastTimeToDisplay = System.nanoTime();
                              dcmsg.setLength(0);
                              dcmsg.append(methodName);
                              dcmsg.append(":scanDisk ++++ cacheName=");
                              dcmsg.append(this.cacheName);
                              dcmsg.append(" DiskCacheSize=");
                              dcmsg.append(getCacheIdsSize());
                              if (this.cod.enableCacheSizeInBytes) {
                                  dcmsg.append("  CacheSizeInBytes=");
                                  dcmsg.append(this.cod.currentCacheSizeInBytes);
                              }
                              dcmsg.append(" ScanExpiredEntries=");
                              dcmsg.append(tScanExpiredCount);
                              dcmsg.append(" ExplicitEntriesDeleted=");
                              dcmsg.append(tExplicitDeleted);
                              dcmsg.append(" ScanEntriesDeleted=");
                              dcmsg.append(tScanDeleted);
                              dcmsg.append(" GCEntriesDeleted=");
                              dcmsg.append(tGCDeleted);
                              dcmsg.append(" DeletedSize=");
                              dcmsg.append(tDeletedSize);
                              dcmsg.append(" ExplicitBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.EXPLICIT_BUFFER));
                              dcmsg.append(" ScanBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.SCAN_BUFFER));
                              dcmsg.append(" GCBuffer=");
                              dcmsg.append(this.invalidationBuffer.size(HTODInvalidationBuffer.GC_BUFFER));
                              dcmsg.append(" CleanupScanPending=");
                              dcmsg.append(this.invalidationBuffer.isCleanupPending());
                              Tr.event(tc, dcmsg.toString());
                          }
                          if (getDiskCacheSizeInfo().doYield(getCacheIdsSize(), this.cod.currentCacheSizeInBytes)) {
                              Thread.yield();
                          }
                      }
                  } else if (!scan) {
                      complete = true;
                  }
                  if (this.invalidationBuffer.isLoopOnce()) {
                      break;
                  }
                  t = System.nanoTime();
                  Result res = deleteEntriesFromInvalidationBuffer(true);
                  tDeleteTime += System.nanoTime() - t;
                  returnCode = res.returnCode;
                  tExplicitDeleted += res.numExplicitDeleted;
                  tScanDeleted += res.numScanDeleted;
                  tGCDeleted += res.numGCDeleted;
                  tDeletedSize += res.deletedSize;
                  returnToResultPool(res);
  
                  if (returnCode == DISK_EXCEPTION) {
                      break;
                  }
                  if (complete || returnCode == DISK_EXCEPTION || this.invalidationBuffer.isLoopOnce()) {
                      break;
                  }
                  i++;
              } while (i > 0);
              this.totalDeleted += (tExplicitDeleted + tScanDeleted + tGCDeleted);
              this.totalDeletedSize += tDeletedSize;
              dcmsg.setLength(0);
              dcmsg.append("  DiskCacheSize=");
              dcmsg.append(getCacheIdsSize());
              dcmsg.append("  DepIdsSize=");
              dcmsg.append(getDepIdsSize());
              dcmsg.append("  TemplatesSize=");
              dcmsg.append(getTemplatesSize());
              if (this.cod.enableCacheSizeInBytes) {
                  dcmsg.append("  CacheSizeInBytes=");
                  dcmsg.append(this.cod.currentCacheSizeInBytes);
              }
              dcmsg.append("  TimeElapsed=");
              dcmsg.append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
              if (tPopulateDepTablesTime != 0) {
                  dcmsg.append("  PopulateDepTablesTime=");
                  dcmsg.append(tPopulateDepTablesTime);
              }
              dcmsg.append("  ScanTime=");
              dcmsg.append(tReadRangeTime);
              dcmsg.append(" ScanExpiredEntries=");
              dcmsg.append(tScanExpiredCount);
              dcmsg.append("  DeleteTime=");
              dcmsg.append(TimeUnit.NANOSECONDS.toMillis(tDeleteTime));
              dcmsg.append("  ExplicitEntriesDeleted=");
              dcmsg.append(tExplicitDeleted);
              dcmsg.append("  ScanEntriesDeleted=");
              dcmsg.append(tScanDeleted);
              dcmsg.append("  GCEntriesDeleted=");
              dcmsg.append(tGCDeleted);
              dcmsg.append("  DeletedSize=");
              dcmsg.append(tDeletedSize);
              dcmsg.append("  totalDeleted=");
              dcmsg.append(this.totalDeleted);
              dcmsg.append("  totalDeletedSize=");
              dcmsg.append(this.totalDeletedSize);
  
              if (scan) {
                  Tr.info(tc, "DYNA0058I", new Object[] { this.cacheName, dcmsg.toString() });
              } else if (!scan && tc.isEventEnabled()) {
                  Tr.event(tc, "The disk cache cleanup finished for cache name \"" + this.cacheName + "\"." + " The statistics are: " + dcmsg.toString());
              } else {
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, methodName, "The disk cache cleanup finished for cache name \"" + this.cacheName + "\"." + " The statistics are: " + dcmsg.toString());
              }
              getDiskCacheSizeInfo().displayDiskCacheInfo();
          }
  
          this.invalidationBuffer.setlastRemoveTime();
          // clear the cache ids table to reduce the memory usage.
          this.cod.populateDependencyTable = false;
          if (cacheIdsTable != null) {
              cacheIdsTable.clear();
              cacheIdsTable = null;
          }
          return returnCode;
      }