* Work-horse for SearchCatCache/SearchCatCacheN. */
| 1251 | * Work-horse for SearchCatCache/SearchCatCacheN. |
| 1252 | */ |
| 1253 | static inline HeapTuple |
| 1254 | SearchCatCacheInternal(CatCache *cache, |
| 1255 | int nkeys, |
| 1256 | Datum v1, |
| 1257 | Datum v2, |
| 1258 | Datum v3, |
| 1259 | Datum v4) |
| 1260 | { |
| 1261 | Datum arguments[CATCACHE_MAXKEYS]; |
| 1262 | uint32 hashValue; |
| 1263 | Index hashIndex; |
| 1264 | dlist_iter iter; |
| 1265 | dlist_head *bucket; |
| 1266 | CatCTup *ct; |
| 1267 | |
| 1268 | /* Make sure we're in an xact, even if this ends up being a cache hit */ |
| 1269 | Assert(IsTransactionState()); |
| 1270 | |
| 1271 | Assert(cache->cc_nkeys == nkeys); |
| 1272 | |
| 1273 | /* |
| 1274 | * one-time startup overhead for each cache |
| 1275 | */ |
| 1276 | if (unlikely(cache->cc_tupdesc == NULL)) |
| 1277 | CatalogCacheInitializeCache(cache); |
| 1278 | |
| 1279 | #ifdef CATCACHE_STATS |
| 1280 | cache->cc_searches++; |
| 1281 | #endif |
| 1282 | |
| 1283 | /* Initialize local parameter array */ |
| 1284 | arguments[0] = v1; |
| 1285 | arguments[1] = v2; |
| 1286 | arguments[2] = v3; |
| 1287 | arguments[3] = v4; |
| 1288 | |
| 1289 | /* |
| 1290 | * find the hash bucket in which to look for the tuple |
| 1291 | */ |
| 1292 | hashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4); |
| 1293 | hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets); |
| 1294 | |
| 1295 | /* |
| 1296 | * scan the hash bucket until we find a match or exhaust our tuples |
| 1297 | * |
| 1298 | * Note: it's okay to use dlist_foreach here, even though we modify the |
| 1299 | * dlist within the loop, because we don't continue the loop afterwards. |
| 1300 | */ |
| 1301 | bucket = &cache->cc_bucket[hashIndex]; |
| 1302 | dlist_foreach(iter, bucket) |
| 1303 | { |
| 1304 | ct = dlist_container(CatCTup, cache_elem, iter.cur); |
| 1305 | |
| 1306 | if (ct->dead) |
| 1307 | continue; /* ignore dead entries */ |
| 1308 | |
| 1309 | if (ct->hash_value != hashValue) |
| 1310 | continue; /* quickly skip entry if wrong hash val */ |
no test coverage detected