MCPcopy Create free account
hub / github.com/apache/cloudberry / cache_reduce_memory

Function cache_reduce_memory

src/backend/executor/nodeMemoize.c:410–484  ·  view source on GitHub ↗

* cache_reduce_memory * Evict older and less recently used items from the cache in order to * reduce the memory consumption back to something below the * MemoizeState's mem_limit. * * 'specialkey', if not NULL, causes the function to return false if the entry * which the key belongs to is removed from the cache. */

Source from the content-addressed store, hash-verified

408 * which the key belongs to is removed from the cache.
409 */
410static bool
411cache_reduce_memory(MemoizeState *mstate, MemoizeKey *specialkey)
412{
413 bool specialkey_intact = true; /* for now */
414 dlist_mutable_iter iter;
415 uint64 evictions = 0;
416
417 /* Update peak memory usage */
418 if (mstate->mem_used > mstate->stats.mem_peak)
419 mstate->stats.mem_peak = mstate->mem_used;
420
421 /* We expect only to be called when we've gone over budget on memory */
422 Assert(mstate->mem_used > mstate->mem_limit);
423
424 /* Start the eviction process starting at the head of the LRU list. */
425 dlist_foreach_modify(iter, &mstate->lru_list)
426 {
427 MemoizeKey *key = dlist_container(MemoizeKey, lru_node, iter.cur);
428 MemoizeEntry *entry;
429
430 /*
431 * Populate the hash probe slot in preparation for looking up this LRU
432 * entry.
433 */
434 prepare_probe_slot(mstate, key);
435
436 /*
437 * Ideally the LRU list pointers would be stored in the entry itself
438 * rather than in the key. Unfortunately, we can't do that as the
439 * simplehash.h code may resize the table and allocate new memory for
440 * entries which would result in those pointers pointing to the old
441 * buckets. However, it's fine to use the key to store this as that's
442 * only referenced by a pointer in the entry, which of course follows
443 * the entry whenever the hash table is resized. Since we only have a
444 * pointer to the key here, we must perform a hash table lookup to
445 * find the entry that the key belongs to.
446 */
447 entry = memoize_lookup(mstate->hashtable, NULL);
448
449 /*
450 * Sanity check that we found the entry belonging to the LRU list
451 * item. A misbehaving hash or equality function could cause the
452 * entry not to be found or the wrong entry to be found.
453 */
454 if (unlikely(entry == NULL || entry->key != key))
455 elog(ERROR, "could not find memoization table entry");
456
457 /*
458 * If we're being called to free memory while the cache is being
459 * populated with new tuples, then we'd better take some care as we
460 * could end up freeing the entry which 'specialkey' belongs to.
461 * Generally callers will pass 'specialkey' as the key for the cache
462 * entry which is currently being populated, so we must set
463 * 'specialkey_intact' to false to inform the caller the specialkey
464 * entry has been removed.
465 */
466 if (key == specialkey)
467 specialkey_intact = false;

Callers 2

cache_lookupFunction · 0.85
cache_store_tupleFunction · 0.85

Calls 2

prepare_probe_slotFunction · 0.85
remove_cache_entryFunction · 0.85

Tested by

no test coverage detected