FlushResult (final @NotNull IndexConfiguration indexes, final @NotNull /*InOut*/ IntRef contentionQuota, final long flushingPeriodMs) { if (System.currentTimeMillis() - lastFlushedMs < flushingPeriodMs) { //no need for another flush yet: return FlushResult.NOTHING_TO_FLUSH_NOW; } final UpdatableIndex<?, ?, FileContent, ?> index = indexes.getIndex(indexId); if (index == null) { //did nothing -> spent no quota: return FlushResult.NOTHING_TO_FLUSH_NOW; } int unspentContentionQuota = contentionQuota.get(); final ReadWriteLock indexProtectingLock = index.getLock(); final Lock indexReadLock = indexProtectingLock.readLock(); final boolean lockSucceeded = indexReadLock.tryLock(); if (lockSucceeded) { try { try { index.flush(); lastFlushedMs = System.currentTimeMillis(); } catch (Throwable e) { requestRebuild(indexId, e); } unspentContentionQuota -= threadsCompetingForLock(indexProtectingLock); contentionQuota.set(unspentContentionQuota); return FlushResult.FLUSHED_ALL; } finally { indexReadLock.unlock(); } } //+1 because of the thread currently holding lock (causing .tryLock to fail) final int competingThreads = threadsCompetingForLock(indexProtectingLock) + 1; unspentContentionQuota -= competingThreads; contentionQuota.set(unspentContentionQuota); return FlushResult.HAS_MORE_TO_FLUSH; }