* SearchCatCacheList * * Generate a list of all tuples matching a partial key (that is, * a key specifying just the first K of the cache's N key columns). * * It doesn't make any sense to specify all of the cache's key columns * here: since the key is unique, there could be at most one match, so * you ought to use SearchCatCache() instead. Hence this function takes * one fewer Datum
| 1570 | * and must call ReleaseCatCacheList() when done with the list. |
| 1571 | */ |
| 1572 | CatCList * |
| 1573 | SearchCatCacheList(CatCache *cache, |
| 1574 | int nkeys, |
| 1575 | Datum v1, |
| 1576 | Datum v2, |
| 1577 | Datum v3) |
| 1578 | { |
| 1579 | Datum v4 = 0; /* dummy last-column value */ |
| 1580 | Datum arguments[CATCACHE_MAXKEYS]; |
| 1581 | uint32 lHashValue; |
| 1582 | dlist_iter iter; |
| 1583 | CatCList *cl; |
| 1584 | CatCTup *ct; |
| 1585 | List *volatile ctlist; |
| 1586 | ListCell *ctlist_item; |
| 1587 | int nmembers; |
| 1588 | bool ordered; |
| 1589 | HeapTuple ntp; |
| 1590 | MemoryContext oldcxt; |
| 1591 | int i; |
| 1592 | |
| 1593 | /* |
| 1594 | * one-time startup overhead for each cache |
| 1595 | */ |
| 1596 | if (cache->cc_tupdesc == NULL) |
| 1597 | CatalogCacheInitializeCache(cache); |
| 1598 | |
| 1599 | Assert(nkeys > 0 && nkeys < cache->cc_nkeys); |
| 1600 | |
| 1601 | #ifdef CATCACHE_STATS |
| 1602 | cache->cc_lsearches++; |
| 1603 | #endif |
| 1604 | |
| 1605 | /* Initialize local parameter array */ |
| 1606 | arguments[0] = v1; |
| 1607 | arguments[1] = v2; |
| 1608 | arguments[2] = v3; |
| 1609 | arguments[3] = v4; |
| 1610 | |
| 1611 | /* |
| 1612 | * compute a hash value of the given keys for faster search. We don't |
| 1613 | * presently divide the CatCList items into buckets, but this still lets |
| 1614 | * us skip non-matching items quickly most of the time. |
| 1615 | */ |
| 1616 | lHashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4); |
| 1617 | |
| 1618 | /* |
| 1619 | * scan the items until we find a match or exhaust our list |
| 1620 | * |
| 1621 | * Note: it's okay to use dlist_foreach here, even though we modify the |
| 1622 | * dlist within the loop, because we don't continue the loop afterwards. |
| 1623 | */ |
| 1624 | dlist_foreach(iter, &cache->cc_lists) |
| 1625 | { |
| 1626 | cl = dlist_container(CatCList, cache_elem, iter.cur); |
| 1627 | |
| 1628 | if (cl->dead) |
| 1629 | continue; /* ignore dead entries */ |
no test coverage detected