Skip to content

Commit c4be17d

Browse files
committed
Merge remote-tracking branch 'origin/candidate-9.4.x' into candidate-9.4.48
Signed-off-by: Gavin Halliday <[email protected]>
2 parents eb92776 + 2f6621c commit c4be17d

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

system/jhtree/jhtree.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ class CNodeMapping : public HTMapping<CNodeCacheEntry, CKeyIdAndPos>
668668
};
669669

670670
typedef OwningSimpleHashTableOf<CNodeMapping, CKeyIdAndPos> CNodeTable;
671-
class CNodeMRUCache : public CMRUCacheOf<CKeyIdAndPos, CNodeCacheEntry, CNodeMapping, CNodeTable>
671+
class CNodeMRUCache final : public CMRUCacheOf<CKeyIdAndPos, CNodeCacheEntry, CNodeMapping, CNodeTable>
672672
{
673673
std::atomic<size32_t> sizeInMem{0};
674674
size32_t memLimit = 0;
@@ -684,15 +684,31 @@ class CNodeMRUCache : public CMRUCacheOf<CKeyIdAndPos, CNodeCacheEntry, CNodeMap
684684
virtual void makeSpace()
685685
{
686686
// remove LRU until !full
687+
// This code could walk the list, rather than restarting at the end each time - but there are unlikely to be
688+
// many entries that have no associated node, and nodes could have been associated in the meantime.
687689
do
688690
{
689-
//Never evict an entry that hasn't yet loaded - otherwise the sizeInMem can become inconsistent
690691
CNodeMapping *tail = mruList.tail();
691-
assertex(tail);
692-
if (!tail->queryElement().isReady() )
693-
break;
692+
if (unlikely(!tail))
693+
throw makeStringExceptionV(9999, "Index cache appears full but contains no entries size=%x limit=%x", sizeInMem.load(), memLimit);
694+
695+
//Never evict an entry that hasn't yet loaded - otherwise the sizeInMem can become inconsistent
696+
//When running with slow remote storage this can take a long time to be ready - so we need
697+
//to walk on to the next entry in the lrulist, otherwise we can run out of memory since nothing
698+
//would be removed.
699+
while (!tail->queryElement().isReady())
700+
{
701+
tail = tail->prev;
702+
if (!tail)
703+
{
704+
// no pages in the cache are ready - this could possibly happen in a tiny race-window where
705+
// sizes in the cache have been updated, but no nodes have yet been associated with the entries.
706+
return;
707+
}
708+
}
694709

695-
clear(1);
710+
mruList.remove(tail);
711+
table.removeExact(tail);
696712
}
697713
while (full());
698714
}

0 commit comments

Comments
 (0)