Skip to content

Commit

Permalink
Improve performance of query cache invalidation
Browse files Browse the repository at this point in the history
We replaced Cache2k cache.invokeAll call by simple map removeIf.
This improved invalidation time (for 40000 cached queries
for simple objects) from 184.38 ms to 45.54 ms (by 75%).

Related to MID-6245.
  • Loading branch information
mederly committed Sep 29, 2021
1 parent dd42448 commit a947a09
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.apache.commons.lang3.tuple.MutablePair;
import org.cache2k.Cache2kBuilder;
import org.cache2k.expiry.ExpiryPolicy;
import org.cache2k.processor.EntryProcessor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

Expand All @@ -29,6 +28,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

import static com.evolveum.midpoint.repo.cache.handlers.SearchOpHandler.QUERY_RESULT_SIZE_LIMIT;

Expand Down Expand Up @@ -107,9 +107,9 @@ public <T extends ObjectType> void put(QueryKey<T> key, @NotNull SearchResultLis
}
}

public void invokeAll(EntryProcessor<QueryKey, GlobalCacheQueryValue, Void> entryProcessor) {
public void deleteMatching(Predicate<Map.Entry<QueryKey, GlobalCacheQueryValue>> predicate) {
if (cache != null) {
cache.invokeAll(cache.keys(), entryProcessor);
cache.asMap().entrySet().removeIf(predicate);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public <T extends ObjectType> void invalidateCacheEntries(Class<T> type, String
new CacheInvalidationContext(false, new RepositoryCacheInvalidationDetails(additionalInfo)));
} catch (Throwable t) {
result.recordFatalError(t);
throw t; // Really? We want the operation to proceed anyway. But OTOH we want to be sure devel team gets notified about this.
throw t; // Really? We want the operation to proceed anyway. But OTOH we want to be sure devel team gets notified about this.
} finally {
result.computeStatusIfUnknown();
}
Expand Down Expand Up @@ -157,15 +157,16 @@ private <T extends ObjectType> void clearQueryResultsGlobally(Class<T> type, Str
AtomicInteger all = new AtomicInteger(0);
AtomicInteger removed = new AtomicInteger(0);

globalQueryCache.invokeAll(entry -> {
globalQueryCache.deleteMatching(entry -> {
QueryKey queryKey = entry.getKey();
all.incrementAndGet();
if (change.mayAffect(queryKey, entry.getValue().getResult(), matchingRuleRegistry)) {
LOGGER.trace("Removing (from global cache) query for type={}, change={}: {}", type, change, queryKey.getQuery());
entry.remove();
removed.incrementAndGet();
return true;
} else {
return false;
}
return null;
});
LOGGER.trace("Removed (from global cache) {} (of {}) query result entries of type {} in {} ms", removed, all, type, System.currentTimeMillis() - start);
}
Expand Down

0 comments on commit a947a09

Please sign in to comment.