* cache_lookup * Perform a lookup to see if we've already cached tuples based on the * scan's current parameters. If we find an existing entry we move it to * the end of the LRU list, set *found to true then return it. If we * don't find an entry then we create a new one and add it to the end of * the LRU list. We also update cache memory accounting and remove older * entries if we
| 496 | * Callers can assume we'll never return NULL when *found is true. |
| 497 | */ |
| 498 | static MemoizeEntry * |
| 499 | cache_lookup(MemoizeState *mstate, bool *found) |
| 500 | { |
| 501 | MemoizeKey *key; |
| 502 | MemoizeEntry *entry; |
| 503 | MemoryContext oldcontext; |
| 504 | |
| 505 | /* prepare the probe slot with the current scan parameters */ |
| 506 | prepare_probe_slot(mstate, NULL); |
| 507 | |
| 508 | /* |
| 509 | * Add the new entry to the cache. No need to pass a valid key since the |
| 510 | * hash function uses mstate's probeslot, which we populated above. |
| 511 | */ |
| 512 | entry = memoize_insert(mstate->hashtable, NULL, found); |
| 513 | |
| 514 | if (*found) |
| 515 | { |
| 516 | /* |
| 517 | * Move existing entry to the tail of the LRU list to mark it as the |
| 518 | * most recently used item. |
| 519 | */ |
| 520 | dlist_move_tail(&mstate->lru_list, &entry->key->lru_node); |
| 521 | |
| 522 | return entry; |
| 523 | } |
| 524 | |
| 525 | oldcontext = MemoryContextSwitchTo(mstate->tableContext); |
| 526 | |
| 527 | /* Allocate a new key */ |
| 528 | entry->key = key = (MemoizeKey *) palloc(sizeof(MemoizeKey)); |
| 529 | key->params = ExecCopySlotMinimalTuple(mstate->probeslot); |
| 530 | |
| 531 | /* Update the total cache memory utilization */ |
| 532 | mstate->mem_used += EMPTY_ENTRY_MEMORY_BYTES(entry); |
| 533 | |
| 534 | /* Initialize this entry */ |
| 535 | entry->complete = false; |
| 536 | entry->tuplehead = NULL; |
| 537 | |
| 538 | /* |
| 539 | * Since this is the most recently used entry, push this entry onto the |
| 540 | * end of the LRU list. |
| 541 | */ |
| 542 | dlist_push_tail(&mstate->lru_list, &entry->key->lru_node); |
| 543 | |
| 544 | mstate->last_tuple = NULL; |
| 545 | |
| 546 | MemoryContextSwitchTo(oldcontext); |
| 547 | |
| 548 | /* |
| 549 | * If we've gone over our memory budget, then we'll free up some space in |
| 550 | * the cache. |
| 551 | */ |
| 552 | if (mstate->mem_used > mstate->mem_limit) |
| 553 | { |
| 554 | /* |
| 555 | * Try to free up some memory. It's highly unlikely that we'll fail |
no test coverage detected