From a9927cde9495f46436443b1113e2997c804e8e07 Mon Sep 17 00:00:00 2001 From: Dom Garguilo Date: Mon, 10 Aug 2026 14:15:42 -0400 Subject: [PATCH] Remove unused extents from tablet locator --- .../core/clientImpl/TabletLocatorImpl.java | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/TabletLocatorImpl.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/TabletLocatorImpl.java index 7bc8d3f4edc..2b2d787f38e 100644 --- a/core/src/main/java/org/apache/accumulo/core/clientImpl/TabletLocatorImpl.java +++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/TabletLocatorImpl.java @@ -21,6 +21,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.apache.accumulo.core.util.UtilWaitThread.sleepUninterruptibly; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -54,11 +55,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; +import com.github.benmanes.caffeine.cache.Scheduler; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; public class TabletLocatorImpl extends TabletLocator { private static final Logger log = LoggerFactory.getLogger(TabletLocatorImpl.class); + private static final Duration CACHE_EXPIRATION = Duration.ofMinutes(10); // MAX_TEXT represents a TEXT object that is greater than all others. Attempted to use null for // this purpose, but there seems to be a bug in TreeMap.tailMap with null. Therefore instead of @@ -80,7 +87,9 @@ public class TabletLocatorImpl extends TabletLocator { protected TableId tableId; protected TabletLocator parent; + // The TreeMap supports range lookups; Caffeine tracks access and expires entries from it. protected TreeMap metaCache = new TreeMap<>(END_ROW_COMPARATOR); + private final Cache extentCache; protected TabletLocationObtainer locationObtainer; private final TabletServerLockChecker lockChecker; protected Text lastTabletRow; @@ -158,10 +167,29 @@ public TabletLocatorImpl(TableId tableId, TabletLocator parent, TabletLocationOb this.locationObtainer = tlo; this.lockChecker = tslc; + extentCache = Caffeine.newBuilder().expireAfterAccess(CACHE_EXPIRATION) + .scheduler(Scheduler.systemScheduler()).removalListener(this::onExtentRemoval).build(); + this.lastTabletRow = new Text(tableId.canonical()); lastTabletRow.append(new byte[] {'<'}, 0, 1); } + private void onExtentRemoval(KeyExtent extent, TabletLocation location, RemovalCause cause) { + if (cause == RemovalCause.REPLACED) { + return; + } + + wLock.lock(); + try { + Text endRow = extent.endRow() == null ? MAX_TEXT : extent.endRow(); + if (metaCache.get(endRow) == location) { + metaCache.remove(endRow); + } + } finally { + wLock.unlock(); + } + } + @Override public void binMutations(ClientContext context, List mutations, Map> binnedMutations, List failures) @@ -465,6 +493,7 @@ public void invalidateCache() { try { invalidatedCount = metaCache.size(); metaCache.clear(); + extentCache.invalidateAll(); } finally { wLock.unlock(); } @@ -596,6 +625,7 @@ private void updateCache(TabletLocation tabletLocation, LockCheckerSession lcSes er = MAX_TEXT; } metaCache.put(er, tabletLocation); + extentCache.put(tabletLocation.tablet_extent, tabletLocation); if (!badExtents.isEmpty()) { removeOverlapping(badExtents, tabletLocation.tablet_extent); @@ -648,9 +678,13 @@ private TabletLocation locateTabletInCache(Text row) { Entry entry = metaCache.ceilingEntry(row); if (entry != null) { - KeyExtent ke = entry.getValue().tablet_extent; + TabletLocation location = extentCache.getIfPresent(entry.getValue().tablet_extent); + if (location == null) { + return null; + } + KeyExtent ke = location.tablet_extent; if (ke.prevEndRow() == null || ke.prevEndRow().compareTo(row) < 0) { - return entry.getValue(); + return location; } } return null;