Remove offsethash

The original motivation was to eliminate the superfluous HnswPtrAccess
call from AddToVisited. The caller has to call HnswPtrAccess() anyway,
so it makes sense to pass the HnswElement rather than HnswElementPtr
to AddToVisited(). But then I realized that we can use the
pointer-variant even with shared memory, because the visited-hash is
backend-private, and the addresses where the elements are mapped to in
shared memory are stable within the backend.
This commit is contained in:
Heikki Linnakangas
2024-02-19 13:55:13 +02:00
parent 5ba62fca84
commit 1cbd204f52
2 changed files with 7 additions and 64 deletions

View File

@@ -445,17 +445,4 @@ typedef struct PointerHashEntry
#define SH_DECLARE #define SH_DECLARE
#include "lib/simplehash.h" #include "lib/simplehash.h"
typedef struct OffsetHashEntry
{
Size offset;
char status;
} OffsetHashEntry;
#define SH_PREFIX offsethash
#define SH_ELEMENT_TYPE OffsetHashEntry
#define SH_KEY_TYPE Size
#define SH_SCOPE extern
#define SH_DECLARE
#include "lib/simplehash.h"
#endif #endif

View File

@@ -81,31 +81,9 @@ hash_pointer(uintptr_t ptr)
#define SH_DEFINE #define SH_DEFINE
#include "lib/simplehash.h" #include "lib/simplehash.h"
/* Offset hash table */
static uint32
hash_offset(Size offset)
{
#if SIZEOF_SIZE_T == 8
return murmurhash64((uint64) offset);
#else
return murmurhash32((uint32) offset);
#endif
}
#define SH_PREFIX offsethash
#define SH_ELEMENT_TYPE OffsetHashEntry
#define SH_KEY_TYPE Size
#define SH_KEY offset
#define SH_HASH_KEY(tb, key) hash_offset(key)
#define SH_EQUAL(tb, a, b) (a == b)
#define SH_SCOPE extern
#define SH_DEFINE
#include "lib/simplehash.h"
typedef union typedef union
{ {
pointerhash_hash *pointers; pointerhash_hash *pointers;
offsethash_hash *offsets;
tidhash_hash *tids; tidhash_hash *tids;
} visited_hash; } visited_hash;
@@ -658,8 +636,6 @@ InitVisited(char *base, visited_hash * v, Relation index, int ef, int m)
{ {
if (index != NULL) if (index != NULL)
v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL);
else if (base != NULL)
v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL);
else else
v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL); v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL);
} }
@@ -668,34 +644,21 @@ InitVisited(char *base, visited_hash * v, Relation index, int ef, int m)
* Add to visited * Add to visited
*/ */
static inline void static inline void
AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, bool *found) AddToVisited(char *base, visited_hash * v, HnswElement element, Relation index, bool *found)
{ {
if (index != NULL) if (index != NULL)
{ {
HnswElement element = HnswPtrAccess(base, hc->element);
ItemPointerData indextid; ItemPointerData indextid;
ItemPointerSet(&indextid, element->blkno, element->offno); ItemPointerSet(&indextid, element->blkno, element->offno);
tidhash_insert(v->tids, indextid, found); tidhash_insert(v->tids, indextid, found);
} }
else if (base != NULL)
{
#if PG_VERSION_NUM >= 130000
HnswElement element = HnswPtrAccess(base, hc->element);
offsethash_insert_hash(v->offsets, HnswPtrOffset(hc->element), element->hash, found);
#else
offsethash_insert(v->offsets, HnswPtrOffset(hc->element), found);
#endif
}
else else
{ {
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
HnswElement element = HnswPtrAccess(base, hc->element); pointerhash_insert_hash(v->pointers, (uintptr_t) element, element->hash, found);
pointerhash_insert_hash(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), element->hash, found);
#else #else
pointerhash_insert(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), found); pointerhash_insert(v->pointers, (uintptr_t) element, found);
#endif #endif
} }
} }
@@ -748,7 +711,7 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F
HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); HnswCandidate *hc = (HnswCandidate *) lfirst(lc2);
bool found; bool found;
AddToVisited(base, &v, hc, index, &found); AddToVisited(base, &v, HnswPtrAccess(base, hc->element), index, &found);
pairingheap_add(C, &(CreatePairingHeapNode(hc)->ph_node)); pairingheap_add(C, &(CreatePairingHeapNode(hc)->ph_node));
pairingheap_add(W, &(CreatePairingHeapNode(hc)->ph_node)); pairingheap_add(W, &(CreatePairingHeapNode(hc)->ph_node));
@@ -792,14 +755,14 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F
for (int i = 0; i < neighborhood->length; i++) for (int i = 0; i < neighborhood->length; i++)
{ {
HnswCandidate *e = &neighborhood->items[i]; HnswCandidate *e = &neighborhood->items[i];
HnswElement eElement = HnswPtrAccess(base, e->element);
bool visited; bool visited;
AddToVisited(base, &v, e, index, &visited); AddToVisited(base, &v, eElement, index, &visited);
if (!visited) if (!visited)
{ {
float eDistance; float eDistance;
HnswElement eElement = HnswPtrAccess(base, e->element);
f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner;
@@ -1180,14 +1143,7 @@ RemoveElements(char *base, List *w, HnswElement skipElement)
static void static void
PrecomputeHash(char *base, HnswElement element) PrecomputeHash(char *base, HnswElement element)
{ {
HnswElementPtr ptr; element->hash = hash_pointer((uintptr_t) element);
HnswPtrStore(base, ptr, element);
if (base == NULL)
element->hash = hash_pointer((uintptr_t) HnswPtrPointer(ptr));
else
element->hash = hash_offset(HnswPtrOffset(ptr));
} }
#endif #endif