mirror of
https://github.com/pgvector/pgvector.git
synced 2026-10-23 10:48:54 +03:00
Reverted casting changes
This commit is contained in:
@@ -59,7 +59,7 @@ BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui
|
||||
memcpy(&axs, ax, sizeof(uint64));
|
||||
memcpy(&bxs, bx, sizeof(uint64));
|
||||
|
||||
distance += (uint64) popcount64(axs ^ bxs);
|
||||
distance += popcount64(axs ^ bxs);
|
||||
|
||||
ax += sizeof(uint64);
|
||||
bx += sizeof(uint64);
|
||||
@@ -108,9 +108,9 @@ BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui
|
||||
memcpy(&axs, ax, sizeof(uint64));
|
||||
memcpy(&bxs, bx, sizeof(uint64));
|
||||
|
||||
ab += (uint64) popcount64(axs & bxs);
|
||||
aa += (uint64) popcount64(axs);
|
||||
bb += (uint64) popcount64(bxs);
|
||||
ab += popcount64(axs & bxs);
|
||||
aa += popcount64(axs);
|
||||
bb += popcount64(bxs);
|
||||
|
||||
ax += sizeof(uint64);
|
||||
bx += sizeof(uint64);
|
||||
@@ -127,7 +127,7 @@ BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui
|
||||
if (ab == 0)
|
||||
return 1;
|
||||
else
|
||||
return 1 - ((double) ab / (double) (aa + bb - ab));
|
||||
return 1 - (ab / ((double) (aa + bb - ab)));
|
||||
}
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
|
||||
@@ -19,7 +19,7 @@ InitBitVector(int dim)
|
||||
VarBit *result;
|
||||
Size size;
|
||||
|
||||
size = VARBITTOTALLEN((Size) dim);
|
||||
size = VARBITTOTALLEN(dim);
|
||||
result = (VarBit *) palloc0(size);
|
||||
SET_VARSIZE(result, size);
|
||||
VARBITLEN(result) = dim;
|
||||
@@ -51,7 +51,7 @@ hamming_distance(PG_FUNCTION_ARGS)
|
||||
|
||||
CheckDims(a, b);
|
||||
|
||||
PG_RETURN_FLOAT8((double) BitHammingDistance((uint32) VARBITBYTES(a), VARBITS(a), VARBITS(b), 0));
|
||||
PG_RETURN_FLOAT8((double) BitHammingDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -66,5 +66,5 @@ jaccard_distance(PG_FUNCTION_ARGS)
|
||||
|
||||
CheckDims(a, b);
|
||||
|
||||
PG_RETURN_FLOAT8(BitJaccardDistance((uint32) VARBITBYTES(a), VARBITS(a), VARBITS(b), 0, 0, 0));
|
||||
PG_RETURN_FLOAT8(BitJaccardDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0, 0, 0));
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
#define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1)
|
||||
#define CreateStateDatums(dim) palloc_array_checked(Datum, (Size) ((dim) + 1))
|
||||
#define CreateStateDatums(dim) palloc_array_checked(Datum, (dim) + 1)
|
||||
|
||||
/*
|
||||
* Get a half from a message buffer
|
||||
@@ -48,7 +48,7 @@ pq_getmsghalf(StringInfo msg)
|
||||
uint16 i;
|
||||
} swap;
|
||||
|
||||
swap.i = (uint16) pq_getmsgint(msg, 2);
|
||||
swap.i = pq_getmsgint(msg, 2);
|
||||
return swap.h;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ InitHalfVector(int dim)
|
||||
size = HALFVEC_SIZE(dim);
|
||||
result = (HalfVector *) palloc0(size);
|
||||
SET_VARSIZE(result, size);
|
||||
result->dim = (int16) dim;
|
||||
result->dim = dim;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -242,7 +242,7 @@ halfvec_in(PG_FUNCTION_ARGS)
|
||||
if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, (Size) (stringEnd - pt)))));
|
||||
errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt))));
|
||||
|
||||
CheckElement(x[dim]);
|
||||
dim++;
|
||||
@@ -310,7 +310,7 @@ halfvec_out(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* 3 bytes for [, ], and \0
|
||||
*/
|
||||
buf = (char *) palloc(add_size(mul_size(FLOAT_SHORTEST_DECIMAL_LEN, (Size) dim), 3));
|
||||
buf = (char *) palloc(add_size(mul_size(FLOAT_SHORTEST_DECIMAL_LEN, dim), 3));
|
||||
ptr = buf;
|
||||
|
||||
AppendChar(ptr, '[');
|
||||
@@ -375,11 +375,11 @@ halfvec_recv(PG_FUNCTION_ARGS)
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
HalfVector *result;
|
||||
int dim;
|
||||
int unused;
|
||||
int16 dim;
|
||||
int16 unused;
|
||||
|
||||
dim = (int) pq_getmsgint(buf, sizeof(int16));
|
||||
unused = (int) pq_getmsgint(buf, sizeof(int16));
|
||||
dim = pq_getmsgint(buf, sizeof(int16));
|
||||
unused = pq_getmsgint(buf, sizeof(int16));
|
||||
|
||||
CheckDim(dim);
|
||||
CheckExpectedDim(typmod, dim);
|
||||
@@ -410,8 +410,8 @@ halfvec_send(PG_FUNCTION_ARGS)
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
pq_sendint16(&buf, (uint16) vec->dim);
|
||||
pq_sendint16(&buf, (uint16) vec->unused);
|
||||
pq_sendint16(&buf, vec->dim);
|
||||
pq_sendint16(&buf, vec->unused);
|
||||
for (int i = 0; i < vec->dim; i++)
|
||||
pq_sendhalf(&buf, vec->x[i]);
|
||||
|
||||
@@ -471,12 +471,12 @@ array_to_halfvec(PG_FUNCTION_ARGS)
|
||||
if (ARR_ELEMTYPE(array) == INT4OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
result->x[i] = Float4ToHalf((float) DatumGetInt32(elemsp[i]));
|
||||
result->x[i] = Float4ToHalf(DatumGetInt32(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT8OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
result->x[i] = Float4ToHalf((float) DatumGetFloat8(elemsp[i]));
|
||||
result->x[i] = Float4ToHalf(DatumGetFloat8(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT4OID)
|
||||
{
|
||||
@@ -519,7 +519,7 @@ halfvec_to_float4(PG_FUNCTION_ARGS)
|
||||
Datum *datums;
|
||||
ArrayType *result;
|
||||
|
||||
datums = palloc_array_checked(Datum, (Size) vec->dim);
|
||||
datums = palloc_array_checked(Datum, vec->dim);
|
||||
|
||||
for (int i = 0; i < vec->dim; i++)
|
||||
datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i]));
|
||||
@@ -745,7 +745,7 @@ halfvec_l2_normalize(PG_FUNCTION_ARGS)
|
||||
if (norm > 0)
|
||||
{
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
rx[i] = Float4ToHalfUnchecked((float) (HalfToFloat4(ax[i]) / norm));
|
||||
rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) / norm);
|
||||
|
||||
/* Check for overflow */
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
@@ -1186,7 +1186,7 @@ halfvec_avg(PG_FUNCTION_ARGS)
|
||||
result = InitHalfVector(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
result->x[i] = Float4ToHalf((float) (statevalues[i + 1] / n));
|
||||
result->x[i] = Float4ToHalf(statevalues[i + 1] / n);
|
||||
CheckElement(result->x[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
#define HALFVEC_MAX_DIM 16000
|
||||
|
||||
#define HALFVEC_SIZE(_dim) add_size(offsetof(HalfVector, x), mul_size(sizeof(half), (Size) (_dim)))
|
||||
#define HALFVEC_SIZE(_dim) add_size(offsetof(HalfVector, x), mul_size(sizeof(half), _dim))
|
||||
#define DatumGetHalfVector(x) ((HalfVector *) PG_DETOAST_DATUM(x))
|
||||
#define PG_GETARG_HALFVEC_P(x) DatumGetHalfVector(PG_GETARG_DATUM(x))
|
||||
#define PG_RETURN_HALFVEC_P(x) PG_RETURN_POINTER(x)
|
||||
|
||||
@@ -79,9 +79,9 @@ typedef Pointer Item;
|
||||
#define HNSW_TUPLE_ALLOC_SIZE BLCKSZ
|
||||
|
||||
#define HNSW_ELEMENT_TUPLE_SIZE(size) MAXALIGN(add_size(offsetof(HnswElementTupleData, data), size))
|
||||
#define HNSW_NEIGHBOR_TUPLE_SIZE(level, m) MAXALIGN(add_size(offsetof(HnswNeighborTupleData, indextids), mul_size(sizeof(ItemPointerData), mul_size(add_size(level, 2), (Size) (m)))))
|
||||
#define HNSW_NEIGHBOR_TUPLE_SIZE(level, m) MAXALIGN(add_size(offsetof(HnswNeighborTupleData, indextids), mul_size(sizeof(ItemPointerData), mul_size(add_size(level, 2), m))))
|
||||
|
||||
#define HNSW_NEIGHBOR_ARRAY_SIZE(lm) add_size(offsetof(HnswNeighborArray, items), mul_size(sizeof(HnswCandidate), (Size) (lm)))
|
||||
#define HNSW_NEIGHBOR_ARRAY_SIZE(lm) add_size(offsetof(HnswNeighborArray, items), mul_size(sizeof(HnswCandidate), lm))
|
||||
|
||||
#define HnswPageGetOpaque(page) ((HnswPageOpaque) PageGetSpecialPointer(page))
|
||||
#define HnswPageGetMeta(page) ((HnswMetaPageData *) PageGetContents(page))
|
||||
@@ -130,7 +130,7 @@ typedef Pointer Item;
|
||||
#define HnswGetMl(m) (1 / log(m))
|
||||
|
||||
/* Ensure fits on page and in uint8 */
|
||||
#define HnswGetMaxLevel(m) Min(((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - offsetof(HnswNeighborTupleData, indextids) - sizeof(ItemIdData)) / sizeof(ItemPointerData) / (Size) (m)) - 2, 63)
|
||||
#define HnswGetMaxLevel(m) Min(((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - offsetof(HnswNeighborTupleData, indextids) - sizeof(ItemIdData)) / (sizeof(ItemPointerData)) / (m)) - 2, 63)
|
||||
|
||||
#define HnswGetSearchCandidate(membername, ptr) pairingheap_container(HnswSearchCandidate, membername, ptr)
|
||||
#define HnswGetSearchCandidateConst(membername, ptr) pairingheap_const_container(HnswSearchCandidate, membername, ptr)
|
||||
|
||||
@@ -102,15 +102,15 @@ CreateMetaPage(HnswBuildState * buildstate)
|
||||
metap = HnswPageGetMeta(page);
|
||||
metap->magicNumber = HNSW_MAGIC_NUMBER;
|
||||
metap->version = HNSW_VERSION;
|
||||
metap->dimensions = (uint32) buildstate->dimensions;
|
||||
metap->m = (uint16) buildstate->m;
|
||||
metap->efConstruction = (uint16) buildstate->efConstruction;
|
||||
metap->dimensions = buildstate->dimensions;
|
||||
metap->m = buildstate->m;
|
||||
metap->efConstruction = buildstate->efConstruction;
|
||||
metap->entryBlkno = InvalidBlockNumber;
|
||||
metap->entryOffno = InvalidOffsetNumber;
|
||||
metap->entryLevel = -1;
|
||||
metap->insertPage = InvalidBlockNumber;
|
||||
((PageHeader) page)->pd_lower =
|
||||
(LocationIndex) (((char *) metap + sizeof(HnswMetaPageData)) - (char *) page);
|
||||
((char *) metap + sizeof(HnswMetaPageData)) - (char *) page;
|
||||
|
||||
MarkBufferDirty(buf);
|
||||
UnlockReleaseBuffer(buf);
|
||||
@@ -599,7 +599,7 @@ BuildCallback(Relation index, ItemPointer tid, Datum *values,
|
||||
{
|
||||
/* Update progress */
|
||||
SpinLockAcquire(&graph->lock);
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, (int64) ++graph->indtuples);
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, ++graph->indtuples);
|
||||
SpinLockRelease(&graph->lock);
|
||||
}
|
||||
|
||||
@@ -721,7 +721,7 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
|
||||
/* Get support functions */
|
||||
HnswInitSupport(&buildstate->support, index);
|
||||
|
||||
InitGraph(&buildstate->graphData, NULL, mul_size((Size) maintenance_work_mem, 1024));
|
||||
InitGraph(&buildstate->graphData, NULL, mul_size(maintenance_work_mem, 1024));
|
||||
buildstate->graph = &buildstate->graphData;
|
||||
buildstate->ml = HnswGetMl(buildstate->m);
|
||||
buildstate->maxLevel = HnswGetMaxLevel(buildstate->m);
|
||||
@@ -958,7 +958,7 @@ HnswBeginParallel(HnswBuildState * buildstate, bool isconcurrent, int request)
|
||||
/* Leave space for other objects in shared memory */
|
||||
/* Docker has a default limit of 64 MB for shm_size */
|
||||
/* which happens to be the default value of maintenance_work_mem */
|
||||
esthnswarea = mul_size((Size) maintenance_work_mem, 1024);
|
||||
esthnswarea = mul_size(maintenance_work_mem, 1024);
|
||||
estother = 3 * 1024 * 1024;
|
||||
if (esthnswarea > estother)
|
||||
esthnswarea -= estother;
|
||||
|
||||
@@ -391,7 +391,7 @@ LoadElementsForInsert(HnswNeighborArray * neighbors, HnswQuery * q, int *idx, Re
|
||||
double distance;
|
||||
|
||||
HnswLoadElement(element, &distance, q, index, support, true, NULL);
|
||||
hc->distance = (float) distance;
|
||||
hc->distance = distance;
|
||||
|
||||
/* Prune element if being deleted */
|
||||
if (element->heaptidsLength == 0)
|
||||
|
||||
@@ -153,7 +153,7 @@ hnswbeginscan(Relation index, int nkeys, int norderbys)
|
||||
/* Calculate max memory */
|
||||
/* Add 256 extra bytes to fill last block when close */
|
||||
maxMemory = (double) work_mem * hnsw_scan_mem_multiplier * 1024.0 + 256;
|
||||
so->maxMemory = (Size) Min(maxMemory, (double) (SIZE_MAX / 2));
|
||||
so->maxMemory = Min(maxMemory, (double) (SIZE_MAX / 2));
|
||||
|
||||
scan->opaque = so;
|
||||
|
||||
@@ -177,10 +177,10 @@ hnswrescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int no
|
||||
MemoryContextReset(so->tmpCtx);
|
||||
|
||||
if (keys && scan->numberOfKeys > 0)
|
||||
memmove(scan->keyData, keys, (Size) scan->numberOfKeys * sizeof(ScanKeyData));
|
||||
memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData));
|
||||
|
||||
if (orderbys && scan->numberOfOrderBys > 0)
|
||||
memmove(scan->orderByData, orderbys, (Size) scan->numberOfOrderBys * sizeof(ScanKeyData));
|
||||
memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -51,7 +51,7 @@ hash_tid(ItemPointerData tid)
|
||||
x.i = 0;
|
||||
x.tid = tid;
|
||||
|
||||
return (uint32) murmurhash64(x.i);
|
||||
return murmurhash64(x.i);
|
||||
}
|
||||
|
||||
#define SH_PREFIX tidhash
|
||||
@@ -69,7 +69,7 @@ static uint32
|
||||
hash_pointer(uintptr_t ptr)
|
||||
{
|
||||
#if SIZEOF_VOID_P == 8
|
||||
return (uint32) murmurhash64((uint64) ptr);
|
||||
return murmurhash64((uint64) ptr);
|
||||
#else
|
||||
return murmurhash32((uint32) ptr);
|
||||
#endif
|
||||
@@ -90,7 +90,7 @@ static uint32
|
||||
hash_offset(Size offset)
|
||||
{
|
||||
#if SIZEOF_SIZE_T == 8
|
||||
return (uint32) murmurhash64((uint64) offset);
|
||||
return murmurhash64((uint64) offset);
|
||||
#else
|
||||
return murmurhash32((uint32) offset);
|
||||
#endif
|
||||
@@ -218,7 +218,7 @@ void
|
||||
HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * allocator)
|
||||
{
|
||||
int level = element->level;
|
||||
HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, mul_size(sizeof(HnswNeighborArrayPtr), add_size((Size) level, 1)));
|
||||
HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, mul_size(sizeof(HnswNeighborArrayPtr), add_size(level, 1)));
|
||||
|
||||
HnswPtrStore(base, element->neighbors, neighborList);
|
||||
|
||||
@@ -256,7 +256,7 @@ HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel,
|
||||
element->heaptidsLength = 0;
|
||||
HnswAddHeapTid(element, heaptid);
|
||||
|
||||
element->level = (uint8) level;
|
||||
element->level = level;
|
||||
element->deleted = 0;
|
||||
/* Start at one to make it easier to find issues */
|
||||
element->version = 1;
|
||||
@@ -319,7 +319,7 @@ HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint)
|
||||
if (BlockNumberIsValid(metap->entryBlkno))
|
||||
{
|
||||
*entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno);
|
||||
(*entryPoint)->level = (uint8) metap->entryLevel;
|
||||
(*entryPoint)->level = metap->entryLevel;
|
||||
}
|
||||
else
|
||||
*entryPoint = NULL;
|
||||
@@ -481,7 +481,7 @@ HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m)
|
||||
}
|
||||
}
|
||||
|
||||
ntup->count = (uint16) idx;
|
||||
ntup->count = idx;
|
||||
ntup->version = e->version;
|
||||
}
|
||||
|
||||
@@ -672,14 +672,12 @@ CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b,
|
||||
static inline void
|
||||
InitVisited(char *base, visited_hash * v, bool inMemory, int ef, int m)
|
||||
{
|
||||
uint32 initialElements = (uint32) ef * (uint32) m * 2;
|
||||
|
||||
if (!inMemory)
|
||||
v->tids = tidhash_create(CurrentMemoryContext, initialElements, NULL);
|
||||
v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL);
|
||||
else if (base != NULL)
|
||||
v->offsets = offsethash_create(CurrentMemoryContext, initialElements, NULL);
|
||||
v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL);
|
||||
else
|
||||
v->pointers = pointerhash_create(CurrentMemoryContext, initialElements, NULL);
|
||||
v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -784,8 +782,8 @@ HnswLoadNeighborTids(HnswElement element, ItemPointerData *indextids, Relation i
|
||||
}
|
||||
|
||||
/* Copy to minimize lock time */
|
||||
start = mul_size((Size) (element->level - lc), (Size) m);
|
||||
memcpy(indextids, ntup->indextids + start, mul_size(sizeof(ItemPointerData), (Size) lm));
|
||||
start = mul_size(element->level - lc, m);
|
||||
memcpy(indextids, ntup->indextids + start, mul_size(sizeof(ItemPointerData), lm));
|
||||
|
||||
UnlockReleaseBuffer(buf);
|
||||
return true;
|
||||
@@ -834,7 +832,7 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in
|
||||
HnswNeighborArray *localNeighborhood = NULL;
|
||||
Size neighborhoodSize = 0;
|
||||
int lm = HnswGetLayerM(m, lc);
|
||||
HnswUnvisited *unvisited = palloc_array_checked(HnswUnvisited, (Size) lm);
|
||||
HnswUnvisited *unvisited = palloc_array_checked(HnswUnvisited, lm);
|
||||
int unvisitedLength;
|
||||
bool inMemory = index == NULL;
|
||||
|
||||
@@ -1050,7 +1048,7 @@ CheckElementCloser(char *base, HnswCandidate * e, List *r, HnswSupport * support
|
||||
HnswCandidate *ri = lfirst(lc2);
|
||||
HnswElement riElement = HnswPtrAccess(base, ri->element);
|
||||
Datum riValue = HnswGetValue(base, riElement);
|
||||
float distance = (float) HnswGetDistance(eValue, riValue, support);
|
||||
float distance = HnswGetDistance(eValue, riValue, support);
|
||||
|
||||
if (distance <= e->distance)
|
||||
return false;
|
||||
@@ -1077,7 +1075,7 @@ SelectNeighbors(char *base, List *c, int lm, HnswSupport * support, bool *closer
|
||||
if (list_length(w) <= lm)
|
||||
return w;
|
||||
|
||||
wd = palloc_array_checked(HnswCandidate *, (Size) list_length(w));
|
||||
wd = palloc_array_checked(HnswCandidate *, list_length(w));
|
||||
|
||||
/* Ensure order of candidates is deterministic for closer caching */
|
||||
if (sortCandidates)
|
||||
@@ -1334,7 +1332,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint
|
||||
HnswCandidate *hc = palloc_object(HnswCandidate);
|
||||
|
||||
hc->element = sc->element;
|
||||
hc->distance = (float) sc->distance;
|
||||
hc->distance = sc->distance;
|
||||
|
||||
lw = lappend(lw, hc);
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum)
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_LOAD);
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_TOTAL, (int64) buildstate->indtuples);
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_TOTAL, buildstate->indtuples);
|
||||
|
||||
GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list);
|
||||
|
||||
@@ -396,7 +396,7 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In
|
||||
buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, buildstate->itemsize);
|
||||
|
||||
/* TODO Move allocation to page creation */
|
||||
buildstate->listInfo = palloc_array_checked(ListInfo, (Size) buildstate->lists);
|
||||
buildstate->listInfo = palloc_array_checked(ListInfo, buildstate->lists);
|
||||
|
||||
buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"Ivfflat build temporary context",
|
||||
@@ -452,7 +452,7 @@ ComputeCenters(IvfflatBuildState * buildstate)
|
||||
numSamples = 10000;
|
||||
|
||||
/* Save memory since will not have more than max tuples */
|
||||
numSamples = Max((int) Min(numSamples, maxTuples), 1);
|
||||
numSamples = Max(Min(numSamples, maxTuples), 1);
|
||||
}
|
||||
|
||||
/* Sample rows */
|
||||
@@ -497,10 +497,10 @@ CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum)
|
||||
metap = IvfflatPageGetMeta(page);
|
||||
metap->magicNumber = IVFFLAT_MAGIC_NUMBER;
|
||||
metap->version = IVFFLAT_VERSION;
|
||||
metap->dimensions = (uint16) dimensions;
|
||||
metap->lists = (uint16) lists;
|
||||
metap->dimensions = dimensions;
|
||||
metap->lists = lists;
|
||||
((PageHeader) page)->pd_lower =
|
||||
(LocationIndex) (((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page);
|
||||
((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page;
|
||||
|
||||
IvfflatCommitBuffer(buf, state);
|
||||
}
|
||||
@@ -671,7 +671,7 @@ IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, S
|
||||
indexInfo = BuildIndexInfo(ivfspool->index);
|
||||
indexInfo->ii_Concurrent = ivfshared->isconcurrent;
|
||||
InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo);
|
||||
memcpy(buildstate.centers->items, ivfcenters, mul_size(buildstate.centers->itemsize, (Size) buildstate.centers->maxlen));
|
||||
memcpy(buildstate.centers->items, ivfcenters, mul_size(buildstate.centers->itemsize, buildstate.centers->maxlen));
|
||||
buildstate.centers->length = buildstate.centers->maxlen;
|
||||
ivfspool->sortstate = InitBuildSortState(buildstate.sortdesc, sortmem, coordinate);
|
||||
buildstate.sortstate = ivfspool->sortstate;
|
||||
@@ -864,7 +864,7 @@ IvfflatBeginParallel(IvfflatBuildState * buildstate, bool isconcurrent, int requ
|
||||
shm_toc_estimate_chunk(&pcxt->estimator, estivfshared);
|
||||
estsort = tuplesort_estimate_shared(scantuplesortstates);
|
||||
shm_toc_estimate_chunk(&pcxt->estimator, estsort);
|
||||
estcenters = mul_size(buildstate->centers->itemsize, (Size) buildstate->centers->maxlen);
|
||||
estcenters = mul_size(buildstate->centers->itemsize, buildstate->centers->maxlen);
|
||||
shm_toc_estimate_chunk(&pcxt->estimator, estcenters);
|
||||
shm_toc_estimate_keys(&pcxt->estimator, 3);
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ typedef struct IvfflatScanOpaqueData
|
||||
|
||||
typedef IvfflatScanOpaqueData * IvfflatScanOpaque;
|
||||
|
||||
#define VECTOR_ARRAY_SIZE(_length, _size) add_size(sizeof(VectorArrayData), mul_size((Size) (_length), MAXALIGN(_size)))
|
||||
#define VECTOR_ARRAY_SIZE(_length, _size) add_size(sizeof(VectorArrayData), mul_size(_length, MAXALIGN(_size)))
|
||||
|
||||
/* Use functions instead of macros to avoid double evaluation */
|
||||
|
||||
@@ -326,7 +326,7 @@ VectorArrayGet(VectorArray arr, int offset)
|
||||
if (offset < 0 || offset >= arr->maxlen)
|
||||
elog(ERROR, "index out of bounds");
|
||||
|
||||
return ((char *) arr->items) + ((Size) offset * arr->itemsize);
|
||||
return ((char *) arr->items) + (offset * arr->itemsize);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -25,7 +25,7 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low
|
||||
{
|
||||
FmgrInfo *procinfo;
|
||||
Oid collation;
|
||||
float *weight = palloc_array_checked(float, (Size) samples->length);
|
||||
float *weight = palloc_array_checked(float, samples->length);
|
||||
int numCenters = centers->maxlen;
|
||||
int numSamples = samples->length;
|
||||
|
||||
@@ -33,7 +33,7 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low
|
||||
collation = index->rd_indcollation[0];
|
||||
|
||||
/* Choose an initial center uniformly at random */
|
||||
VectorArraySet(centers, 0, VectorArrayGet(samples, (int) ((uint32) RandomInt() % (uint32) samples->length)));
|
||||
VectorArraySet(centers, 0, VectorArrayGet(samples, RandomInt() % samples->length));
|
||||
centers->length++;
|
||||
|
||||
for (int i = 0; i < numSamples; i++)
|
||||
@@ -59,13 +59,13 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low
|
||||
distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i))));
|
||||
|
||||
/* Set lower bound */
|
||||
lowerBound[(Size) j * (Size) numCenters + (Size) i] = (float) distance;
|
||||
lowerBound[(Size) j * numCenters + i] = distance;
|
||||
|
||||
/* Use distance squared for weighted probability distribution */
|
||||
distance *= distance;
|
||||
|
||||
if (distance < weight[j])
|
||||
weight[j] = (float) distance;
|
||||
weight[j] = distance;
|
||||
|
||||
sum += weight[j];
|
||||
}
|
||||
@@ -113,7 +113,7 @@ RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeI
|
||||
int dimensions = centers->dim;
|
||||
FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC);
|
||||
Oid collation = index->rd_indcollation[0];
|
||||
float *x = palloc_array_checked(float, (Size) dimensions);
|
||||
float *x = palloc_array_checked(float, dimensions);
|
||||
|
||||
/* Fill with random data */
|
||||
while (centers->length < centers->maxlen)
|
||||
@@ -153,7 +153,7 @@ SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTy
|
||||
{
|
||||
for (int i = 0; i < samples->length; i++)
|
||||
{
|
||||
float *x = agg + ((Size) closestCenters[i] * (Size) samples->dim);
|
||||
float *x = agg + ((Size) closestCenters[i] * samples->dim);
|
||||
|
||||
typeInfo->sumCenter(VectorArrayGet(samples, i), x);
|
||||
}
|
||||
@@ -167,7 +167,7 @@ UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo)
|
||||
{
|
||||
for (int i = 0; i < centers->length; i++)
|
||||
{
|
||||
float *x = agg + ((Size) i * (Size) centers->dim);
|
||||
float *x = agg + ((Size) i * centers->dim);
|
||||
|
||||
typeInfo->updateCenter(VectorArrayGet(centers, i), centers->dim, x);
|
||||
}
|
||||
@@ -186,7 +186,7 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *
|
||||
/* Reset sum and count */
|
||||
for (int i = 0; i < numCenters; i++)
|
||||
{
|
||||
float *x = agg + ((Size) i * (Size) dimensions);
|
||||
float *x = agg + ((Size) i * dimensions);
|
||||
|
||||
for (int j = 0; j < dimensions; j++)
|
||||
x[j] = 0.0;
|
||||
@@ -204,7 +204,7 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *
|
||||
/* Divide sum by count */
|
||||
for (int i = 0; i < numCenters; i++)
|
||||
{
|
||||
float *x = agg + ((Size) i * (Size) dimensions);
|
||||
float *x = agg + ((Size) i * dimensions);
|
||||
|
||||
if (centerCounts[i] > 0)
|
||||
{
|
||||
@@ -217,13 +217,13 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *
|
||||
}
|
||||
|
||||
for (int j = 0; j < dimensions; j++)
|
||||
x[j] /= (float) centerCounts[i];
|
||||
x[j] /= centerCounts[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO Handle empty centers properly */
|
||||
for (int j = 0; j < dimensions; j++)
|
||||
x[j] = (float) RandomDouble();
|
||||
x[j] = RandomDouble();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,14 +264,14 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
|
||||
/* Calculate allocation sizes */
|
||||
Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize);
|
||||
Size aggSize = mul_size(sizeof(float), mul_size((Size) numCenters, (Size) dimensions));
|
||||
Size centerCountsSize = mul_size(sizeof(int), (Size) numCenters);
|
||||
Size closestCentersSize = mul_size(sizeof(int), (Size) numSamples);
|
||||
Size lowerBoundSize = mul_size(sizeof(float), mul_size((Size) numSamples, (Size) numCenters));
|
||||
Size upperBoundSize = mul_size(sizeof(float), (Size) numSamples);
|
||||
Size sSize = mul_size(sizeof(float), (Size) numCenters);
|
||||
Size halfcdistSize = mul_size(sizeof(float), mul_size((Size) numCenters, (Size) numCenters));
|
||||
Size newcdistSize = mul_size(sizeof(float), (Size) numCenters);
|
||||
Size aggSize = mul_size(sizeof(float), mul_size(numCenters, dimensions));
|
||||
Size centerCountsSize = mul_size(sizeof(int), numCenters);
|
||||
Size closestCentersSize = mul_size(sizeof(int), numSamples);
|
||||
Size lowerBoundSize = mul_size(sizeof(float), mul_size(numSamples, numCenters));
|
||||
Size upperBoundSize = mul_size(sizeof(float), numSamples);
|
||||
Size sSize = mul_size(sizeof(float), numCenters);
|
||||
Size halfcdistSize = mul_size(sizeof(float), mul_size(numCenters, numCenters));
|
||||
Size newcdistSize = mul_size(sizeof(float), numCenters);
|
||||
|
||||
/* Calculate total size */
|
||||
Size totalSize = memoryUsed;
|
||||
@@ -330,7 +330,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
for (int k = 0; k < numCenters; k++)
|
||||
{
|
||||
/* TODO Use Lemma 1 in k-means++ initialization */
|
||||
float distance = lowerBound[(Size) j * (Size) numCenters + (Size) k];
|
||||
float distance = lowerBound[(Size) j * numCenters + k];
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
@@ -359,10 +359,10 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
|
||||
for (int k = j + 1; k < numCenters; k++)
|
||||
{
|
||||
float distance = (float) (0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))));
|
||||
float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k))));
|
||||
|
||||
halfcdist[(Size) j * (Size) numCenters + (Size) k] = distance;
|
||||
halfcdist[(Size) k * (Size) numCenters + (Size) j] = distance;
|
||||
halfcdist[(Size) j * numCenters + k] = distance;
|
||||
halfcdist[(Size) k * numCenters + j] = distance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
if (j == k)
|
||||
continue;
|
||||
|
||||
distance = halfcdist[(Size) j * (Size) numCenters + (Size) k];
|
||||
distance = halfcdist[(Size) j * numCenters + k];
|
||||
if (distance < minDistance)
|
||||
minDistance = distance;
|
||||
}
|
||||
@@ -407,10 +407,10 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
if (k == closestCenters[j])
|
||||
continue;
|
||||
|
||||
if (upperBound[j] <= lowerBound[(Size) j * (Size) numCenters + (Size) k])
|
||||
if (upperBound[j] <= lowerBound[(Size) j * numCenters + k])
|
||||
continue;
|
||||
|
||||
if (upperBound[j] <= halfcdist[(Size) closestCenters[j] * (Size) numCenters + (Size) k])
|
||||
if (upperBound[j] <= halfcdist[(Size) closestCenters[j] * numCenters + k])
|
||||
continue;
|
||||
|
||||
vec = PointerGetDatum(VectorArrayGet(samples, j));
|
||||
@@ -418,10 +418,10 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
/* Step 3a */
|
||||
if (rj)
|
||||
{
|
||||
dxcx = (float) DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j]))));
|
||||
dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j]))));
|
||||
|
||||
/* d(x,c(x)) computed, which is a form of d(x,c) */
|
||||
lowerBound[(Size) j * (Size) numCenters + (Size) closestCenters[j]] = dxcx;
|
||||
lowerBound[(Size) j * numCenters + closestCenters[j]] = dxcx;
|
||||
upperBound[j] = dxcx;
|
||||
|
||||
rj = false;
|
||||
@@ -430,12 +430,12 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
dxcx = upperBound[j];
|
||||
|
||||
/* Step 3b */
|
||||
if (dxcx > lowerBound[(Size) j * (Size) numCenters + (Size) k] || dxcx > halfcdist[(Size) closestCenters[j] * (Size) numCenters + (Size) k])
|
||||
if (dxcx > lowerBound[(Size) j * numCenters + k] || dxcx > halfcdist[(Size) closestCenters[j] * numCenters + k])
|
||||
{
|
||||
float dxc = (float) DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k))));
|
||||
float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k))));
|
||||
|
||||
/* d(x,c) calculated */
|
||||
lowerBound[(Size) j * (Size) numCenters + (Size) k] = dxc;
|
||||
lowerBound[(Size) j * numCenters + k] = dxc;
|
||||
|
||||
if (dxc < dxcx)
|
||||
{
|
||||
@@ -455,18 +455,18 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
|
||||
/* Step 5 */
|
||||
for (int j = 0; j < numCenters; j++)
|
||||
newcdist[j] = (float) DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j))));
|
||||
newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j))));
|
||||
|
||||
for (int j = 0; j < numSamples; j++)
|
||||
{
|
||||
for (int k = 0; k < numCenters; k++)
|
||||
{
|
||||
float distance = lowerBound[(Size) j * (Size) numCenters + (Size) k] - newcdist[k];
|
||||
float distance = lowerBound[(Size) j * numCenters + k] - newcdist[k];
|
||||
|
||||
if (distance < 0)
|
||||
distance = 0;
|
||||
|
||||
lowerBound[(Size) j * (Size) numCenters + (Size) k] = distance;
|
||||
lowerBound[(Size) j * numCenters + k] = distance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff
|
||||
static void
|
||||
CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo)
|
||||
{
|
||||
float *scratch = palloc_array_checked(float, (Size) centers->dim);
|
||||
float *scratch = palloc_array_checked(float, centers->dim);
|
||||
|
||||
for (int i = 0; i < centers->length; i++)
|
||||
{
|
||||
|
||||
@@ -318,9 +318,9 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
|
||||
so->bas = GetAccessStrategy(BAS_BULKREAD);
|
||||
|
||||
so->listQueue = pairingheap_allocate(CompareLists, scan);
|
||||
so->listPages = palloc_array_checked(BlockNumber, (Size) maxProbes);
|
||||
so->listPages = palloc_array_checked(BlockNumber, maxProbes);
|
||||
so->listIndex = 0;
|
||||
so->lists = palloc_array_checked(IvfflatScanList, (Size) maxProbes);
|
||||
so->lists = palloc_array_checked(IvfflatScanList, maxProbes);
|
||||
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
|
||||
@@ -348,10 +348,10 @@ ivfflatrescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int
|
||||
}
|
||||
|
||||
if (keys && scan->numberOfKeys > 0)
|
||||
memmove(scan->keyData, keys, (Size) scan->numberOfKeys * sizeof(ScanKeyData));
|
||||
memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData));
|
||||
|
||||
if (orderbys && scan->numberOfOrderBys > 0)
|
||||
memmove(scan->orderByData, orderbys, (Size) scan->numberOfOrderBys * sizeof(ScanKeyData));
|
||||
memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,7 +37,7 @@ VectorArrayInit(int maxlen, int dimensions, Size itemsize)
|
||||
res->maxlen = maxlen;
|
||||
res->dim = dimensions;
|
||||
res->itemsize = itemsize;
|
||||
res->items = palloc_extended(mul_size((Size) maxlen, itemsize), MCXT_ALLOC_ZERO | MCXT_ALLOC_HUGE);
|
||||
res->items = palloc_extended(mul_size(maxlen, itemsize), MCXT_ALLOC_ZERO | MCXT_ALLOC_HUGE);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ HalfvecItemSize(int dimensions)
|
||||
static Size
|
||||
BitItemSize(int dimensions)
|
||||
{
|
||||
return VARBITTOTALLEN((Size) dimensions);
|
||||
return VARBITTOTALLEN(dimensions);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -304,7 +304,7 @@ VectorUpdateCenter(Pointer v, int dimensions, float *x)
|
||||
Vector *vec = (Vector *) v;
|
||||
|
||||
SET_VARSIZE(vec, VECTOR_SIZE(dimensions));
|
||||
vec->dim = (int16) dimensions;
|
||||
vec->dim = dimensions;
|
||||
|
||||
for (int i = 0; i < dimensions; i++)
|
||||
vec->x[i] = x[i];
|
||||
@@ -316,7 +316,7 @@ HalfvecUpdateCenter(Pointer v, int dimensions, float *x)
|
||||
HalfVector *vec = (HalfVector *) v;
|
||||
|
||||
SET_VARSIZE(vec, HALFVEC_SIZE(dimensions));
|
||||
vec->dim = (int16) dimensions;
|
||||
vec->dim = dimensions;
|
||||
|
||||
for (int i = 0; i < dimensions; i++)
|
||||
vec->x[i] = Float4ToHalfUnchecked(x[i]);
|
||||
@@ -328,7 +328,7 @@ BitUpdateCenter(Pointer v, int dimensions, float *x)
|
||||
VarBit *vec = (VarBit *) v;
|
||||
unsigned char *nx = VARBITS(vec);
|
||||
|
||||
SET_VARSIZE(vec, VARBITTOTALLEN((Size) dimensions));
|
||||
SET_VARSIZE(vec, VARBITTOTALLEN(dimensions));
|
||||
VARBITLEN(vec) = dimensions;
|
||||
|
||||
for (uint32 i = 0; i < VARBITBYTES(vec); i++)
|
||||
|
||||
@@ -206,8 +206,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *lit = PG_GETARG_CSTRING(0);
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
int dim;
|
||||
long ldim;
|
||||
long dim;
|
||||
char *pt = lit;
|
||||
char *stringEnd;
|
||||
SparseVector *result;
|
||||
@@ -230,7 +229,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ)));
|
||||
|
||||
elements = palloc_array_checked(SparseInputElement, (Size) maxNnz);
|
||||
elements = palloc_array_checked(SparseInputElement, maxNnz);
|
||||
|
||||
pt = lit;
|
||||
|
||||
@@ -316,7 +315,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
if (errno == ERANGE && (value == 0 || isinf(value)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, (Size) (stringEnd - pt)))));
|
||||
errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt))));
|
||||
|
||||
CheckElement(value);
|
||||
|
||||
@@ -324,7 +323,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
if (value != 0)
|
||||
{
|
||||
/* Convert 1-based numbering (SQL) to 0-based (C) */
|
||||
elements[nnz].index = (int32) (index - 1);
|
||||
elements[nnz].index = index - 1;
|
||||
elements[nnz].value = value;
|
||||
nnz++;
|
||||
}
|
||||
@@ -363,7 +362,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
pt++;
|
||||
|
||||
/* Use similar logic as int2vectorin */
|
||||
ldim = strtol(pt, &stringEnd, 10);
|
||||
dim = strtol(pt, &stringEnd, 10);
|
||||
|
||||
if (stringEnd == pt)
|
||||
ereport(ERROR,
|
||||
@@ -371,12 +370,10 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
errmsg("invalid input syntax for type sparsevec: \"%s\"", lit)));
|
||||
|
||||
/* Keep in int range for correct error message later */
|
||||
if (ldim > INT_MAX)
|
||||
ldim = INT_MAX;
|
||||
else if (ldim < INT_MIN)
|
||||
ldim = INT_MIN;
|
||||
|
||||
dim = (int) ldim;
|
||||
if (dim > INT_MAX)
|
||||
dim = INT_MAX;
|
||||
else if (dim < INT_MIN)
|
||||
dim = INT_MIN;
|
||||
|
||||
pt = stringEnd;
|
||||
|
||||
@@ -393,7 +390,7 @@ sparsevec_in(PG_FUNCTION_ARGS)
|
||||
CheckDim(dim);
|
||||
CheckExpectedDim(typmod, dim);
|
||||
|
||||
qsort(elements, (Size) nnz, sizeof(SparseInputElement), CompareIndices);
|
||||
qsort(elements, nnz, sizeof(SparseInputElement), CompareIndices);
|
||||
|
||||
result = InitSparseVector(dim, nnz);
|
||||
rvalues = SPARSEVEC_VALUES(result);
|
||||
@@ -450,7 +447,7 @@ sparsevec_out(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* 4 bytes for {, }, /, and \0
|
||||
*/
|
||||
buf = (char *) palloc(add_size(mul_size(12 + FLOAT_SHORTEST_DECIMAL_LEN, (Size) sparsevec->nnz), 15));
|
||||
buf = (char *) palloc(add_size(mul_size(12 + FLOAT_SHORTEST_DECIMAL_LEN, sparsevec->nnz), 15));
|
||||
ptr = buf;
|
||||
|
||||
AppendChar(ptr, '{');
|
||||
@@ -521,9 +518,9 @@ sparsevec_recv(PG_FUNCTION_ARGS)
|
||||
int32 unused;
|
||||
float *values;
|
||||
|
||||
dim = (int32) pq_getmsgint(buf, sizeof(int32));
|
||||
nnz = (int32) pq_getmsgint(buf, sizeof(int32));
|
||||
unused = (int32) pq_getmsgint(buf, sizeof(int32));
|
||||
dim = pq_getmsgint(buf, sizeof(int32));
|
||||
nnz = pq_getmsgint(buf, sizeof(int32));
|
||||
unused = pq_getmsgint(buf, sizeof(int32));
|
||||
|
||||
CheckDim(dim);
|
||||
CheckNnz(nnz, dim);
|
||||
@@ -540,7 +537,7 @@ sparsevec_recv(PG_FUNCTION_ARGS)
|
||||
/* Binary representation uses zero-based numbering for indices */
|
||||
for (int i = 0; i < nnz; i++)
|
||||
{
|
||||
result->indices[i] = (int32) pq_getmsgint(buf, sizeof(int32));
|
||||
result->indices[i] = pq_getmsgint(buf, sizeof(int32));
|
||||
CheckIndex(result->indices, i, dim);
|
||||
}
|
||||
|
||||
@@ -570,13 +567,13 @@ sparsevec_send(PG_FUNCTION_ARGS)
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
pq_sendint32(&buf, (uint32) svec->dim);
|
||||
pq_sendint32(&buf, (uint32) svec->nnz);
|
||||
pq_sendint32(&buf, (uint32) svec->unused);
|
||||
pq_sendint32(&buf, svec->dim);
|
||||
pq_sendint32(&buf, svec->nnz);
|
||||
pq_sendint32(&buf, svec->unused);
|
||||
|
||||
/* Binary representation uses zero-based numbering for indices */
|
||||
for (int i = 0; i < svec->nnz; i++)
|
||||
pq_sendint32(&buf, (uint32) svec->indices[i]);
|
||||
pq_sendint32(&buf, svec->indices[i]);
|
||||
|
||||
for (int i = 0; i < svec->nnz; i++)
|
||||
pq_sendfloat4(&buf, values[i]);
|
||||
@@ -725,20 +722,20 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* /fp:fast may not propagate +/-Infinity or NaN */
|
||||
#define IS_NOT_ZERO(v) (isnan(v) || isinf(v) || (v) != 0.0f)
|
||||
#define IS_NOT_ZERO(v) (isnan((float) (v)) || isinf((float) (v)) || ((float) (v)) != 0)
|
||||
#else
|
||||
#define IS_NOT_ZERO(v) ((v) != 0.0f)
|
||||
#define IS_NOT_ZERO(v) (((float) (v)) != 0)
|
||||
#endif
|
||||
|
||||
if (ARR_ELEMTYPE(array) == INT4OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
nnz += IS_NOT_ZERO((float) DatumGetInt32(elemsp[i]));
|
||||
nnz += IS_NOT_ZERO(DatumGetInt32(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT8OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
nnz += IS_NOT_ZERO((float) DatumGetFloat8(elemsp[i]));
|
||||
nnz += IS_NOT_ZERO(DatumGetFloat8(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT4OID)
|
||||
{
|
||||
@@ -763,7 +760,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
|
||||
|
||||
#define PROCESS_ARRAY_ELEM(elem) \
|
||||
do { \
|
||||
float v = (elem); \
|
||||
float v = (float) (elem); \
|
||||
if (IS_NOT_ZERO(v)) { \
|
||||
/* Safety check */ \
|
||||
if (j >= result->nnz) \
|
||||
@@ -777,12 +774,12 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
|
||||
if (ARR_ELEMTYPE(array) == INT4OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
PROCESS_ARRAY_ELEM((float) DatumGetInt32(elemsp[i]));
|
||||
PROCESS_ARRAY_ELEM(DatumGetInt32(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT8OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
PROCESS_ARRAY_ELEM((float) DatumGetFloat8(elemsp[i]));
|
||||
PROCESS_ARRAY_ELEM(DatumGetFloat8(elemsp[i]));
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT4OID)
|
||||
{
|
||||
@@ -1107,7 +1104,7 @@ sparsevec_l2_normalize(PG_FUNCTION_ARGS)
|
||||
for (int i = 0; i < a->nnz; i++)
|
||||
{
|
||||
result->indices[i] = a->indices[i];
|
||||
rx[i] = (float) (ax[i] / norm);
|
||||
rx[i] = ax[i] / norm;
|
||||
|
||||
if (isinf(rx[i]))
|
||||
float_overflow_error();
|
||||
|
||||
@@ -35,15 +35,15 @@ SPARSEVEC_SIZE(int nnz)
|
||||
{
|
||||
Size size = offsetof(SparseVector, indices);
|
||||
|
||||
size = add_size(size, mul_size(sizeof(int32), (Size) nnz));
|
||||
size = add_size(size, mul_size(sizeof(float), (Size) nnz));
|
||||
size = add_size(size, mul_size(sizeof(int32), nnz));
|
||||
size = add_size(size, mul_size(sizeof(float), nnz));
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline float *
|
||||
SPARSEVEC_VALUES(SparseVector * x)
|
||||
{
|
||||
return (float *) (((char *) x) + offsetof(SparseVector, indices) + ((Size) x->nnz * sizeof(int32)));
|
||||
return (float *) (((char *) x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32)));
|
||||
}
|
||||
|
||||
SparseVector *InitSparseVector(int dim, int nnz);
|
||||
|
||||
30
src/vector.c
30
src/vector.c
@@ -37,7 +37,7 @@
|
||||
#endif
|
||||
|
||||
#define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1)
|
||||
#define CreateStateDatums(dim) palloc_array_checked(Datum, (Size) ((dim) + 1))
|
||||
#define CreateStateDatums(dim) palloc_array_checked(Datum, (dim) + 1)
|
||||
|
||||
#if defined(USE_TARGET_CLONES) && !defined(__FMA__)
|
||||
#define VECTOR_TARGET_CLONES __attribute__((target_clones("default", "fma")))
|
||||
@@ -134,7 +134,7 @@ InitVector(int dim)
|
||||
size = VECTOR_SIZE(dim);
|
||||
result = (Vector *) palloc0(size);
|
||||
SET_VARSIZE(result, size);
|
||||
result->dim = (int16) dim;
|
||||
result->dim = dim;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ vector_in(PG_FUNCTION_ARGS)
|
||||
if (errno == ERANGE && isinf(val))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, (Size) (stringEnd - pt)))));
|
||||
errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt))));
|
||||
|
||||
CheckElement(val);
|
||||
x[dim++] = val;
|
||||
@@ -305,7 +305,7 @@ vector_out(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* 3 bytes for [, ], and \0
|
||||
*/
|
||||
buf = (char *) palloc(add_size(mul_size(FLOAT_SHORTEST_DECIMAL_LEN, (Size) dim), 3));
|
||||
buf = (char *) palloc(add_size(mul_size(FLOAT_SHORTEST_DECIMAL_LEN, dim), 3));
|
||||
ptr = buf;
|
||||
|
||||
AppendChar(ptr, '[');
|
||||
@@ -378,11 +378,11 @@ vector_recv(PG_FUNCTION_ARGS)
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
Vector *result;
|
||||
int dim;
|
||||
int unused;
|
||||
int16 dim;
|
||||
int16 unused;
|
||||
|
||||
dim = (int) pq_getmsgint(buf, sizeof(int16));
|
||||
unused = (int) pq_getmsgint(buf, sizeof(int16));
|
||||
dim = pq_getmsgint(buf, sizeof(int16));
|
||||
unused = pq_getmsgint(buf, sizeof(int16));
|
||||
|
||||
CheckDim(dim);
|
||||
CheckExpectedDim(typmod, dim);
|
||||
@@ -413,8 +413,8 @@ vector_send(PG_FUNCTION_ARGS)
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
pq_sendint16(&buf, (uint16) vec->dim);
|
||||
pq_sendint16(&buf, (uint16) vec->unused);
|
||||
pq_sendint16(&buf, vec->dim);
|
||||
pq_sendint16(&buf, vec->unused);
|
||||
for (int i = 0; i < vec->dim; i++)
|
||||
pq_sendfloat4(&buf, vec->x[i]);
|
||||
|
||||
@@ -474,12 +474,12 @@ array_to_vector(PG_FUNCTION_ARGS)
|
||||
if (ARR_ELEMTYPE(array) == INT4OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
result->x[i] = (float) DatumGetInt32(elemsp[i]);
|
||||
result->x[i] = DatumGetInt32(elemsp[i]);
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT8OID)
|
||||
{
|
||||
for (int i = 0; i < nelemsp; i++)
|
||||
result->x[i] = (float) DatumGetFloat8(elemsp[i]);
|
||||
result->x[i] = DatumGetFloat8(elemsp[i]);
|
||||
}
|
||||
else if (ARR_ELEMTYPE(array) == FLOAT4OID)
|
||||
{
|
||||
@@ -522,7 +522,7 @@ vector_to_float4(PG_FUNCTION_ARGS)
|
||||
Datum *datums;
|
||||
ArrayType *result;
|
||||
|
||||
datums = palloc_array_checked(Datum, (Size) vec->dim);
|
||||
datums = palloc_array_checked(Datum, vec->dim);
|
||||
|
||||
for (int i = 0; i < vec->dim; i++)
|
||||
datums[i] = Float4GetDatum(vec->x[i]);
|
||||
@@ -805,7 +805,7 @@ l2_normalize(PG_FUNCTION_ARGS)
|
||||
if (norm > 0)
|
||||
{
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
rx[i] = (float) (ax[i] / norm);
|
||||
rx[i] = ax[i] / norm;
|
||||
|
||||
/* Check for overflow */
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
@@ -1310,7 +1310,7 @@ vector_avg(PG_FUNCTION_ARGS)
|
||||
result = InitVector(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
result->x[i] = (float) (statevalues[i + 1] / n);
|
||||
result->x[i] = statevalues[i + 1] / n;
|
||||
CheckElement(result->x[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define VECTOR_MAX_DIM 16000
|
||||
|
||||
#define VECTOR_SIZE(_dim) add_size(offsetof(Vector, x), mul_size(sizeof(float), (Size) (_dim)))
|
||||
#define VECTOR_SIZE(_dim) add_size(offsetof(Vector, x), mul_size(sizeof(float), _dim))
|
||||
#define DatumGetVector(x) ((Vector *) PG_DETOAST_DATUM(x))
|
||||
#define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x))
|
||||
#define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x)
|
||||
|
||||
Reference in New Issue
Block a user