/* * hash_search -- look up key in table and perform action * hash_search_with_hash_value -- same, with key's hash value already computed * * action is one of: * HASH_FIND: look up key in table * HASH_ENTER: look up key in table, creating entry if not present * HASH_ENTER_NULL: same, but return NULL if out of memory * HASH_REMOVE: look up key in table, remove entry if present * * Return value is a pointer to the element found/entered/removed if any, * or NULL if no match was found. (NB: in the case of the REMOVE action, * the result is a dangling pointer that shouldn't be dereferenced!) * * HASH_ENTER will normally ereport a generic "out of memory" error if * it is unable to create a new entry. The HASH_ENTER_NULL operation is * the same except it will return NULL if out of memory. Note that * HASH_ENTER_NULL cannot be used with the default palloc-based allocator, * since palloc internally ereports on out-of-memory. * * If foundPtr isn't NULL, then *foundPtr is set TRUE if we found an * existing entry in the table, FALSE otherwise. This is needed in the * HASH_ENTER case, but is redundant with the return value otherwise. * * For hash_search_with_hash_value, the hashvalue parameter must have been * calculated with get_hash_value(). */ void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr) { return hash_search_with_hash_value(hashp, keyPtr, hashp->hash(keyPtr, hashp->keysize), action, foundPtr); }
/* * BufTableDelete * Delete the hashtable entry for given tag (which must exist) * * Caller must hold exclusive lock on BufMappingLock for tag's partition */ void BufTableDelete(BufferTag *tagPtr, uint32 hashcode) { BufferLookupEnt *result; result = (BufferLookupEnt *) hash_search_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, HASH_REMOVE, NULL); if (!result) /* shouldn't happen */ elog(ERROR, "shared buffer hash table corrupted"); }
/* * BufTableLookup * Lookup the given BufferTag; return buffer ID, or -1 if not found * * Caller must hold at least share lock on BufMappingLock for tag's partition */ int BufTableLookup(BufferTag *tagPtr, uint32 hashcode) { BufferLookupEnt *result; result = (BufferLookupEnt *) hash_search_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, HASH_FIND, NULL); if (!result) return -1; return result->id; }
/* * BufTableInsert * Insert a hashtable entry for given tag and buffer ID, * unless an entry already exists for that tag * * Returns -1 on successful insertion. If a conflicting entry exists * already, returns the buffer ID in that entry. * * Caller must hold exclusive lock on BufMappingLock for tag's partition */ int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id) { BufferLookupEnt *result; bool found; Assert(buf_id >= 0); /* -1 is reserved for not-in-table */ Assert(tagPtr->blockNum != P_NEW); /* invalid tag */ result = (BufferLookupEnt *) hash_search_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, HASH_ENTER, &found); if (found) /* found something already in the table */ return result->id; result->id = buf_id; return -1; }