@Override
  public void refresh(String source) throws EngineException {
    // we obtain a read lock here, since we don't want a flush to happen while we are refreshing
    // since it flushes the index as well (though, in terms of concurrency, we are allowed to do it)
    try (ReleasableLock lock = readLock.acquire()) {
      ensureOpen();
      searcherManager.maybeRefreshBlocking();
    } catch (AlreadyClosedException e) {
      ensureOpen();
      maybeFailEngine("refresh", e);
    } catch (EngineClosedException e) {
      throw e;
    } catch (Throwable t) {
      failEngine("refresh failed", t);
      throw new RefreshFailedEngineException(shardId, t);
    }

    // TODO: maybe we should just put a scheduled job in threadPool?
    // We check for pruning in each delete request, but we also prune here e.g. in case a delete
    // burst comes in and then no more deletes
    // for a long time:
    maybePruneDeletedTombstones();
    versionMapRefreshPending.set(false);
    mergeScheduler.refreshConfig();
  }
  @Override
  public List<Segment> segments(boolean verbose) {
    try (ReleasableLock lock = readLock.acquire()) {
      Segment[] segmentsArr = getSegmentInfo(lastCommittedSegmentInfos, verbose);

      // fill in the merges flag
      Set<OnGoingMerge> onGoingMerges = mergeScheduler.onGoingMerges();
      for (OnGoingMerge onGoingMerge : onGoingMerges) {
        for (SegmentCommitInfo segmentInfoPerCommit : onGoingMerge.getMergedSegments()) {
          for (Segment segment : segmentsArr) {
            if (segment.getName().equals(segmentInfoPerCommit.info.name)) {
              segment.mergeId = onGoingMerge.getId();
              break;
            }
          }
        }
      }
      return Arrays.asList(segmentsArr);
    }
  }
 public MergeStats getMergeStats() {
   return mergeScheduler.stats();
 }
 public void onSettingsChanged() {
   mergeScheduler.refreshConfig();
   // config().isEnableGcDeletes() or config.getGcDeletesInMillis() may have changed:
   maybePruneDeletedTombstones();
 }