Compare commits

...

28 Commits
ci6 ... v0.6.1

Author SHA1 Message Date
Andrew Kane
c6ddf62a29 Version bump to 0.6.1 [skip ci] 2024-03-04 10:27:59 -08:00
Andrew Kane
801be04d8b Updated CI [skip ci] 2024-03-02 17:06:11 -08:00
Andrew Kane
587e9ba97c Added link to bulk loading example [skip ci] 2024-02-29 21:25:11 -08:00
Andrew Kane
d57047a935 Moved COPY example and added FORMAT [skip ci] 2024-02-29 20:35:01 -08:00
oneturkmen
f1db1f17e3 Update README.md (#472) 2024-02-29 20:27:53 -08:00
Andrew Kane
2f48c0fac4 Updated changelog [skip ci] 2024-02-29 18:10:19 -08:00
Andrew Kane
84a8aa8176 Added note about HNSW build time [skip ci] 2024-02-29 16:25:58 -08:00
Andrew Kane
f64ebbef50 Added OPTFLAGS to readme [skip ci] 2024-02-29 16:15:22 -08:00
Andrew Kane
ac8156509b Updated vector operators for <= and >= 2024-02-29 15:43:29 -08:00
Andrew Kane
82bf69b479 Fixed vector subtraction being marked as commutative - fixes #475 2024-02-29 14:36:18 -08:00
Andrew Kane
4be2f57916 Updated license year [skip ci] 2024-02-29 13:44:58 -08:00
Andrew Kane
91e3d2905f Fixed sort function for Postgres 12 2024-02-28 16:26:41 -08:00
Andrew Kane
fe2406564f Replaced pairing heap with array in SelectNeighbors - closes #447
Co-authored-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>
2024-02-28 15:47:26 -08:00
Andrew Kane
fa52511eaa Fixed closer caching for Postgres 12 2024-02-28 15:44:38 -08:00
Andrew Kane
447ef4d27a Specify Postgres version for Valgrind [skip ci] 2024-02-28 14:16:48 -08:00
Andrew Kane
b36cd22ccc Enable assertions on CI 2024-02-28 14:15:34 -08:00
Andrew Kane
b447ae4989 Avoid base address for relptr for Postgres < 14.5 2024-02-28 14:10:14 -08:00
Andrew Kane
efed873a3e Revert "Replaced pairing heap with array in SelectNeighbors - closes #447"
This reverts commit 14b278dec9.
2024-02-28 11:33:14 -08:00
Andrew Kane
14b278dec9 Replaced pairing heap with array in SelectNeighbors - closes #447
Co-authored-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>
2024-02-28 11:25:12 -08:00
Andrew Kane
133a728e48 Updated changelog [skip ci] 2024-02-20 16:38:05 -08:00
Andrew Kane
ca10cbaa7d Revert "Remove offsethash"
This reverts commit 1cbd204f52.
2024-02-20 16:07:32 -08:00
Andrew Kane
eb29019a14 Revert "Eliminate a few HnswPtrAccess invocations"
This reverts commit 334c386a45.
2024-02-20 16:07:21 -08:00
Heikki Linnakangas
334c386a45 Eliminate a few HnswPtrAccess invocations
HnswPtrAccess() is pretty cheap, but it stills seems worthwhile to
avoid repeated calls in the hot paths when it can be easily avoided.
2024-02-19 14:13:18 +02:00
Heikki Linnakangas
1cbd204f52 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.
2024-02-19 14:12:26 +02:00
Andrew Kane
5ba62fca84 Fixed crash with shared_preload_libraries - fixes #460 2024-02-14 17:13:30 -08:00
Andrew Kane
22cb2a3fe7 Simplified Docker tasks [skip ci] 2024-02-07 12:03:33 -08:00
Andrew Kane
72b144906a Added Valgrind to CI 2024-02-07 09:43:01 -08:00
Andrew Kane
a618c1bc78 Updated port name [skip ci] 2024-02-06 12:43:20 -08:00
14 changed files with 105 additions and 41 deletions

View File

@@ -28,7 +28,7 @@ jobs:
dev-files: true dev-files: true
- run: make - run: make
env: env:
PG_CFLAGS: -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare PG_CFLAGS: -DUSE_ASSERT_CHECKING -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare
- run: | - run: |
export PG_CONFIG=`which pg_config` export PG_CONFIG=`which pg_config`
sudo --preserve-env=PG_CONFIG make install sudo --preserve-env=PG_CONFIG make install
@@ -49,7 +49,7 @@ jobs:
postgres-version: 14 postgres-version: 14
- run: make - run: make
env: env:
PG_CFLAGS: -Wall -Wextra -Werror -Wno-unused-parameter PG_CFLAGS: -DUSE_ASSERT_CHECKING -Wall -Wextra -Werror -Wno-unused-parameter
- run: make install - run: make install
- run: make installcheck - run: make installcheck
- if: ${{ failure() }} - if: ${{ failure() }}
@@ -60,7 +60,9 @@ jobs:
wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_14_10.tar.gz wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_14_10.tar.gz
tar xf REL_14_10.tar.gz tar xf REL_14_10.tar.gz
- run: make prove_installcheck PROVE_FLAGS="-I ./postgres-REL_14_10/src/test/perl" PERL5LIB="/Users/runner/perl5/lib/perl5" - run: make prove_installcheck PROVE_FLAGS="-I ./postgres-REL_14_10/src/test/perl" PERL5LIB="/Users/runner/perl5/lib/perl5"
- run: make clean && /usr/local/opt/llvm@15/bin/scan-build --status-bugs make PG_CFLAGS="-DUSE_ASSERT_CHECKING" - run: make clean && /usr/local/opt/llvm@15/bin/scan-build --status-bugs make
env:
PG_CFLAGS: -DUSE_ASSERT_CHECKING
windows: windows:
runs-on: windows-latest runs-on: windows-latest
if: ${{ !startsWith(github.ref_name, 'mac') }} if: ${{ !startsWith(github.ref_name, 'mac') }}
@@ -97,4 +99,15 @@ jobs:
sudo -u postgres make installcheck sudo -u postgres make installcheck
sudo -u postgres make prove_installcheck sudo -u postgres make prove_installcheck
env: env:
PG_CFLAGS: -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare PG_CFLAGS: -DUSE_ASSERT_CHECKING -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare
valgrind:
if: ${{ !startsWith(github.ref_name, 'mac') && !startsWith(github.ref_name, 'windows') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ankane/setup-postgres-valgrind@v1
with:
postgres-version: 16
- run: make
- run: sudo --preserve-env=PG_CONFIG make install
- run: make installcheck

View File

@@ -1,6 +1,8 @@
## 0.6.1 (unreleased) ## 0.6.1 (2024-03-04)
- Fixed error with `ANALYZE` and vectors with different dimensions - Fixed error with `ANALYZE` and vectors with different dimensions
- Fixed error with `shared_preload_libraries`
- Fixed vector subtraction being marked as commutative
## 0.6.0 (2024-01-29) ## 0.6.0 (2024-01-29)

View File

@@ -1,4 +1,4 @@
Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California Portions Copyright (c) 1994, The Regents of the University of California

View File

@@ -2,7 +2,7 @@
"name": "vector", "name": "vector",
"abstract": "Open-source vector similarity search for Postgres", "abstract": "Open-source vector similarity search for Postgres",
"description": "Supports L2 distance, inner product, and cosine distance", "description": "Supports L2 distance, inner product, and cosine distance",
"version": "0.6.0", "version": "0.6.1",
"maintainer": [ "maintainer": [
"Andrew Kane <andrew@ankane.org>" "Andrew Kane <andrew@ankane.org>"
], ],
@@ -20,7 +20,7 @@
"vector": { "vector": {
"file": "sql/vector.sql", "file": "sql/vector.sql",
"docfile": "README.md", "docfile": "README.md",
"version": "0.6.0", "version": "0.6.1",
"abstract": "Open-source vector similarity search for Postgres" "abstract": "Open-source vector similarity search for Postgres"
} }
}, },

View File

@@ -1,5 +1,5 @@
EXTENSION = vector EXTENSION = vector
EXTVERSION = 0.6.0 EXTVERSION = 0.6.1
MODULE_big = vector MODULE_big = vector
DATA = $(wildcard sql/*--*.sql) DATA = $(wildcard sql/*--*.sql)
@@ -71,11 +71,9 @@ PG_MAJOR ?= 16
.PHONY: docker .PHONY: docker
docker: docker:
docker build --pull --no-cache --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:pg$(PG_MAJOR) . docker build --pull --no-cache --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:pg$(PG_MAJOR) -t pgvector/pgvector:$(EXTVERSION)-pg$(PG_MAJOR) .
docker build --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:$(EXTVERSION)-pg$(PG_MAJOR) .
.PHONY: docker-release .PHONY: docker-release
docker-release: docker-release:
docker buildx build --push --pull --no-cache --platform linux/amd64,linux/arm64 --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:pg$(PG_MAJOR) . docker buildx build --push --pull --no-cache --platform linux/amd64,linux/arm64 --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:pg$(PG_MAJOR) -t pgvector/pgvector:$(EXTVERSION)-pg$(PG_MAJOR) .
docker buildx build --push --platform linux/amd64,linux/arm64 --build-arg PG_MAJOR=$(PG_MAJOR) -t pgvector/pgvector:$(EXTVERSION)-pg$(PG_MAJOR) .

View File

@@ -1,5 +1,5 @@
EXTENSION = vector EXTENSION = vector
EXTVERSION = 0.6.0 EXTVERSION = 0.6.1
OBJS = src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\vector.obj OBJS = src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\vector.obj
HEADERS = src\vector.h HEADERS = src\vector.h

View File

@@ -20,7 +20,7 @@ Compile and install the extension (supports Postgres 12+)
```sh ```sh
cd /tmp cd /tmp
git clone --branch v0.6.0 https://github.com/pgvector/pgvector.git git clone --branch v0.6.1 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
make make
make install # may need sudo make install # may need sudo
@@ -44,7 +44,7 @@ Then use `nmake` to build:
```cmd ```cmd
set "PGROOT=C:\Program Files\PostgreSQL\16" set "PGROOT=C:\Program Files\PostgreSQL\16"
git clone --branch v0.6.0 https://github.com/pgvector/pgvector.git git clone --branch v0.6.1 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
nmake /F Makefile.win nmake /F Makefile.win
nmake /F Makefile.win install nmake /F Makefile.win install
@@ -102,6 +102,12 @@ Insert vectors
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'); INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
``` ```
Or load vectors in bulk using `COPY` ([example](https://github.com/pgvector/pgvector-python/blob/master/examples/bulk_loading.py))
```sql
COPY items (embedding) FROM STDIN WITH (FORMAT BINARY);
```
Upsert vectors Upsert vectors
```sql ```sql
@@ -264,6 +270,8 @@ HINT: Increase maintenance_work_mem to speed up builds.
Note: Do not set `maintenance_work_mem` so high that it exhausts the memory on the server Note: Do not set `maintenance_work_mem` so high that it exhausts the memory on the server
Like other index types, its faster to create an index after loading your initial data
Starting with 0.6.0, you can also speed up index creation by increasing the number of parallel workers (2 by default) Starting with 0.6.0, you can also speed up index creation by increasing the number of parallel workers (2 by default)
```sql ```sql
@@ -656,6 +664,14 @@ Note: Replace `16` with your Postgres server version
If compilation fails and the output includes `warning: no such sysroot directory` on Mac, reinstall Xcode Command Line Tools. If compilation fails and the output includes `warning: no such sysroot directory` on Mac, reinstall Xcode Command Line Tools.
### Portability
To compile for portability, use:
```sh
make OPTFLAGS=""
```
## Additional Installation Methods ## Additional Installation Methods
### Docker ### Docker
@@ -671,7 +687,7 @@ This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres) (r
You can also build the image manually: You can also build the image manually:
```sh ```sh
git clone --branch v0.6.0 https://github.com/pgvector/pgvector.git git clone --branch v0.6.1 https://github.com/pgvector/pgvector.git
cd pgvector cd pgvector
docker build --build-arg PG_MAJOR=16 -t myuser/pgvector . docker build --build-arg PG_MAJOR=16 -t myuser/pgvector .
``` ```
@@ -727,7 +743,7 @@ pkg install postgresql15-pg_vector
or the port with: or the port with:
```sh ```sh
cd /usr/ports/databases/pg_vector cd /usr/ports/databases/pgvector
make install make install
``` ```

View File

@@ -0,0 +1,16 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION vector UPDATE TO '0.6.1'" to load this file. \quit
DROP OPERATOR - (vector, vector);
CREATE OPERATOR - (
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub
);
ALTER OPERATOR <= (vector, vector) SET (
RESTRICT = scalarlesel, JOIN = scalarlejoinsel
);
ALTER OPERATOR >= (vector, vector) SET (
RESTRICT = scalargesel, JOIN = scalargejoinsel
);

View File

@@ -180,8 +180,7 @@ CREATE OPERATOR + (
); );
CREATE OPERATOR - ( CREATE OPERATOR - (
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub, LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_sub
COMMUTATOR = -
); );
CREATE OPERATOR * ( CREATE OPERATOR * (
@@ -195,11 +194,10 @@ CREATE OPERATOR < (
RESTRICT = scalarltsel, JOIN = scalarltjoinsel RESTRICT = scalarltsel, JOIN = scalarltjoinsel
); );
-- should use scalarlesel and scalarlejoinsel, but not supported in Postgres < 11
CREATE OPERATOR <= ( CREATE OPERATOR <= (
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_le, LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_le,
COMMUTATOR = >= , NEGATOR = > , COMMUTATOR = >= , NEGATOR = > ,
RESTRICT = scalarltsel, JOIN = scalarltjoinsel RESTRICT = scalarlesel, JOIN = scalarlejoinsel
); );
CREATE OPERATOR = ( CREATE OPERATOR = (
@@ -214,11 +212,10 @@ CREATE OPERATOR <> (
RESTRICT = eqsel, JOIN = eqjoinsel RESTRICT = eqsel, JOIN = eqjoinsel
); );
-- should use scalargesel and scalargejoinsel, but not supported in Postgres < 11
CREATE OPERATOR >= ( CREATE OPERATOR >= (
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ge, LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_ge,
COMMUTATOR = <= , NEGATOR = < , COMMUTATOR = <= , NEGATOR = < ,
RESTRICT = scalargtsel, JOIN = scalargtjoinsel RESTRICT = scalargesel, JOIN = scalargejoinsel
); );
CREATE OPERATOR > ( CREATE OPERATOR > (

View File

@@ -8,6 +8,7 @@
#include "commands/progress.h" #include "commands/progress.h"
#include "commands/vacuum.h" #include "commands/vacuum.h"
#include "hnsw.h" #include "hnsw.h"
#include "miscadmin.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/selfuncs.h" #include "utils/selfuncs.h"
@@ -28,7 +29,7 @@ static relopt_kind hnsw_relopt_kind;
* this grows bigger, we should use a shmem_request_hook and * this grows bigger, we should use a shmem_request_hook and
* RequestAddinShmemSpace() to pre-reserve space for this. * RequestAddinShmemSpace() to pre-reserve space for this.
*/ */
static void void
HnswInitLockTranche(void) HnswInitLockTranche(void)
{ {
int *tranche_ids; int *tranche_ids;
@@ -53,7 +54,8 @@ HnswInitLockTranche(void)
void void
HnswInit(void) HnswInit(void)
{ {
HnswInitLockTranche(); if (!process_shared_preload_libraries_in_progress)
HnswInitLockTranche();
hnsw_relopt_kind = add_reloption_kind(); hnsw_relopt_kind = add_reloption_kind();
add_int_reloption(hnsw_relopt_kind, "m", "Max number of connections", add_int_reloption(hnsw_relopt_kind, "m", "Max number of connections",

View File

@@ -80,7 +80,7 @@
#if PG_VERSION_NUM < 130000 #if PG_VERSION_NUM < 130000
#define list_delete_last(list) list_truncate(list, list_length(list) - 1) #define list_delete_last(list) list_truncate(list, list_length(list) - 1)
#define list_sort(list, cmp) list_qsort(list, cmp) #define list_sort(list, cmp) ((list) = list_qsort(list, cmp))
#endif #endif
#define HnswIsElementTuple(tup) ((tup)->type == HNSW_ELEMENT_TUPLE_TYPE) #define HnswIsElementTuple(tup) ((tup)->type == HNSW_ELEMENT_TUPLE_TYPE)
@@ -389,6 +389,7 @@ void HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation i
void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element); void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element);
void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation); void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation);
void HnswLoadNeighbors(HnswElement element, Relation index, int m); void HnswLoadNeighbors(HnswElement element, Relation index, int m);
void HnswInitLockTranche(void);
PGDLLEXPORT void HnswParallelBuildMain(dsm_segment *seg, shm_toc *toc); PGDLLEXPORT void HnswParallelBuildMain(dsm_segment *seg, shm_toc *toc);
/* Index access methods */ /* Index access methods */

View File

@@ -601,6 +601,9 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values,
static void static void
InitGraph(HnswGraph * graph, char *base, long memoryTotal) InitGraph(HnswGraph * graph, char *base, long memoryTotal)
{ {
/* Initialize the lock tranche if needed */
HnswInitLockTranche();
HnswPtrStore(base, graph->head, (HnswElement) NULL); HnswPtrStore(base, graph->head, (HnswElement) NULL);
HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL); HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL);
graph->memoryUsed = 0; graph->memoryUsed = 0;
@@ -974,6 +977,14 @@ HnswBeginParallel(HnswBuildState * buildstate, bool isconcurrent, int request)
/* Report less than allocated so never fails */ /* Report less than allocated so never fails */
InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024); InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024);
/*
* Avoid base address for relptr for Postgres < 14.5
* https://github.com/postgres/postgres/commit/7201cd18627afc64850537806da7f22150d1a83b
*/
#if PG_VERSION_NUM < 140005
hnswshared->graphData.memoryUsed += MAXALIGN(1);
#endif
shm_toc_insert(pcxt->toc, PARALLEL_KEY_HNSW_SHARED, hnswshared); shm_toc_insert(pcxt->toc, PARALLEL_KEY_HNSW_SHARED, hnswshared);
shm_toc_insert(pcxt->toc, PARALLEL_KEY_HNSW_AREA, hnswarea); shm_toc_insert(pcxt->toc, PARALLEL_KEY_HNSW_AREA, hnswarea);

View File

@@ -860,12 +860,15 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F
static int static int
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
CompareCandidateDistances(const ListCell *a, const ListCell *b) CompareCandidateDistances(const ListCell *a, const ListCell *b)
{
HnswCandidate *hca = lfirst(a);
HnswCandidate *hcb = lfirst(b);
#else #else
CompareCandidateDistances(const void *a, const void *b) CompareCandidateDistances(const void *a, const void *b)
#endif
{ {
HnswCandidate *hca = lfirst((ListCell *) a); HnswCandidate *hca = lfirst(*(ListCell **) a);
HnswCandidate *hcb = lfirst((ListCell *) b); HnswCandidate *hcb = lfirst(*(ListCell **) b);
#endif
if (hca->distance < hcb->distance) if (hca->distance < hcb->distance)
return 1; return 1;
@@ -888,12 +891,15 @@ CompareCandidateDistances(const void *a, const void *b)
static int static int
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b) CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b)
{
HnswCandidate *hca = lfirst(a);
HnswCandidate *hcb = lfirst(b);
#else #else
CompareCandidateDistancesOffset(const void *a, const void *b) CompareCandidateDistancesOffset(const void *a, const void *b)
#endif
{ {
HnswCandidate *hca = lfirst((ListCell *) a); HnswCandidate *hca = lfirst(*(ListCell **) a);
HnswCandidate *hcb = lfirst((ListCell *) b); HnswCandidate *hcb = lfirst(*(ListCell **) b);
#endif
if (hca->distance < hcb->distance) if (hca->distance < hcb->distance)
return 1; return 1;
@@ -952,7 +958,9 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col
{ {
List *r = NIL; List *r = NIL;
List *w = list_copy(c); List *w = list_copy(c);
pairingheap *wd; HnswCandidate **wd;
int wdlen = 0;
int wdoff = 0;
HnswNeighborArray *neighbors = HnswGetNeighbors(base, e2, lc); HnswNeighborArray *neighbors = HnswGetNeighbors(base, e2, lc);
bool mustCalculate = !neighbors->closerSet; bool mustCalculate = !neighbors->closerSet;
List *added = NIL; List *added = NIL;
@@ -961,7 +969,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col
if (list_length(w) <= lm) if (list_length(w) <= lm)
return w; return w;
wd = pairingheap_allocate(CompareNearestCandidates, NULL); wd = palloc(sizeof(HnswCandidate *) * list_length(w));
/* Ensure order of candidates is deterministic for closer caching */ /* Ensure order of candidates is deterministic for closer caching */
if (sortCandidates) if (sortCandidates)
@@ -1027,21 +1035,21 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col
if (e->closer) if (e->closer)
r = lappend(r, e); r = lappend(r, e);
else else
pairingheap_add(wd, &(CreatePairingHeapNode(e)->ph_node)); wd[wdlen++] = e;
} }
/* Cached value can only be used in future if sorted deterministically */ /* Cached value can only be used in future if sorted deterministically */
neighbors->closerSet = sortCandidates; neighbors->closerSet = sortCandidates;
/* Keep pruned connections */ /* Keep pruned connections */
while (!pairingheap_is_empty(wd) && list_length(r) < lm) while (wdoff < wdlen && list_length(r) < lm)
r = lappend(r, ((HnswPairingHeapNode *) pairingheap_remove_first(wd))->inner); r = lappend(r, wd[wdoff++]);
/* Return pruned for update connections */ /* Return pruned for update connections */
if (pruned != NULL) if (pruned != NULL)
{ {
if (!pairingheap_is_empty(wd)) if (wdoff < wdlen)
*pruned = ((HnswPairingHeapNode *) pairingheap_first(wd))->inner; *pruned = wd[wdoff];
else else
*pruned = linitial(w); *pruned = linitial(w);
} }

View File

@@ -1,4 +1,4 @@
comment = 'vector data type and ivfflat and hnsw access methods' comment = 'vector data type and ivfflat and hnsw access methods'
default_version = '0.6.0' default_version = '0.6.1'
module_pathname = '$libdir/vector' module_pathname = '$libdir/vector'
relocatable = true relocatable = true