|
|
|
|
@@ -11,7 +11,7 @@
|
|
|
|
|
* Find the list that minimizes the distance function
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
FindInsertPage(Relation rel, Datum *values, BlockNumber *insertPage, ListInfo * listInfo)
|
|
|
|
|
FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo * listInfo)
|
|
|
|
|
{
|
|
|
|
|
double minDistance = DBL_MAX;
|
|
|
|
|
BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO;
|
|
|
|
|
@@ -22,8 +22,8 @@ FindInsertPage(Relation rel, Datum *values, BlockNumber *insertPage, ListInfo *
|
|
|
|
|
listInfo->blkno = nextblkno;
|
|
|
|
|
listInfo->offno = FirstOffsetNumber;
|
|
|
|
|
|
|
|
|
|
procinfo = index_getprocinfo(rel, 1, IVFFLAT_DISTANCE_PROC);
|
|
|
|
|
collation = rel->rd_indcollation[0];
|
|
|
|
|
procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC);
|
|
|
|
|
collation = index->rd_indcollation[0];
|
|
|
|
|
|
|
|
|
|
/* Search all list pages */
|
|
|
|
|
while (BlockNumberIsValid(nextblkno))
|
|
|
|
|
@@ -32,7 +32,7 @@ FindInsertPage(Relation rel, Datum *values, BlockNumber *insertPage, ListInfo *
|
|
|
|
|
Page cpage;
|
|
|
|
|
OffsetNumber maxoffno;
|
|
|
|
|
|
|
|
|
|
cbuf = ReadBuffer(rel, nextblkno);
|
|
|
|
|
cbuf = ReadBuffer(index, nextblkno);
|
|
|
|
|
LockBuffer(cbuf, BUFFER_LOCK_SHARE);
|
|
|
|
|
cpage = BufferGetPage(cbuf);
|
|
|
|
|
maxoffno = PageGetMaxOffsetNumber(cpage);
|
|
|
|
|
@@ -64,7 +64,7 @@ FindInsertPage(Relation rel, Datum *values, BlockNumber *insertPage, ListInfo *
|
|
|
|
|
* Insert a tuple into the index
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRel)
|
|
|
|
|
InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRel)
|
|
|
|
|
{
|
|
|
|
|
IndexTuple itup;
|
|
|
|
|
Datum value;
|
|
|
|
|
@@ -81,20 +81,20 @@ InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Rel
|
|
|
|
|
value = PointerGetDatum(PG_DETOAST_DATUM(values[0]));
|
|
|
|
|
|
|
|
|
|
/* Normalize if needed */
|
|
|
|
|
normprocinfo = IvfflatOptionalProcInfo(rel, IVFFLAT_NORM_PROC);
|
|
|
|
|
normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC);
|
|
|
|
|
if (normprocinfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
if (!IvfflatNormValue(normprocinfo, rel->rd_indcollation[0], &value, NULL))
|
|
|
|
|
if (!IvfflatNormValue(normprocinfo, index->rd_indcollation[0], &value, NULL))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find the insert page - sets the page and list info */
|
|
|
|
|
FindInsertPage(rel, values, &insertPage, &listInfo);
|
|
|
|
|
FindInsertPage(index, values, &insertPage, &listInfo);
|
|
|
|
|
Assert(BlockNumberIsValid(insertPage));
|
|
|
|
|
originalInsertPage = insertPage;
|
|
|
|
|
|
|
|
|
|
/* Form tuple */
|
|
|
|
|
itup = index_form_tuple(RelationGetDescr(rel), &value, isnull);
|
|
|
|
|
itup = index_form_tuple(RelationGetDescr(index), &value, isnull);
|
|
|
|
|
itup->t_tid = *heap_tid;
|
|
|
|
|
|
|
|
|
|
/* Get tuple size */
|
|
|
|
|
@@ -104,10 +104,10 @@ InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Rel
|
|
|
|
|
/* Find a page to insert the item */
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
buf = ReadBuffer(rel, insertPage);
|
|
|
|
|
buf = ReadBuffer(index, insertPage);
|
|
|
|
|
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
|
|
|
|
|
|
|
|
|
state = GenericXLogStart(rel);
|
|
|
|
|
state = GenericXLogStart(index);
|
|
|
|
|
page = GenericXLogRegisterBuffer(state, buf, 0);
|
|
|
|
|
|
|
|
|
|
if (PageGetFreeSpace(page) >= itemsz)
|
|
|
|
|
@@ -127,9 +127,9 @@ InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Rel
|
|
|
|
|
Page newpage;
|
|
|
|
|
|
|
|
|
|
/* Add a new page */
|
|
|
|
|
LockRelationForExtension(rel, ExclusiveLock);
|
|
|
|
|
newbuf = IvfflatNewBuffer(rel, MAIN_FORKNUM);
|
|
|
|
|
UnlockRelationForExtension(rel, ExclusiveLock);
|
|
|
|
|
LockRelationForExtension(index, ExclusiveLock);
|
|
|
|
|
newbuf = IvfflatNewBuffer(index, MAIN_FORKNUM);
|
|
|
|
|
UnlockRelationForExtension(index, ExclusiveLock);
|
|
|
|
|
|
|
|
|
|
/* Init new page */
|
|
|
|
|
newpage = GenericXLogRegisterBuffer(state, newbuf, GENERIC_XLOG_FULL_IMAGE);
|
|
|
|
|
@@ -150,7 +150,7 @@ InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Rel
|
|
|
|
|
UnlockReleaseBuffer(buf);
|
|
|
|
|
|
|
|
|
|
/* Prepare new buffer */
|
|
|
|
|
state = GenericXLogStart(rel);
|
|
|
|
|
state = GenericXLogStart(index);
|
|
|
|
|
buf = newbuf;
|
|
|
|
|
page = GenericXLogRegisterBuffer(state, buf, 0);
|
|
|
|
|
break;
|
|
|
|
|
@@ -159,13 +159,13 @@ InsertTuple(Relation rel, Datum *values, bool *isnull, ItemPointer heap_tid, Rel
|
|
|
|
|
|
|
|
|
|
/* Add to next offset */
|
|
|
|
|
if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber)
|
|
|
|
|
elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(rel));
|
|
|
|
|
elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index));
|
|
|
|
|
|
|
|
|
|
IvfflatCommitBuffer(buf, state);
|
|
|
|
|
|
|
|
|
|
/* Update the insert page */
|
|
|
|
|
if (insertPage != originalInsertPage)
|
|
|
|
|
IvfflatUpdateList(rel, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM);
|
|
|
|
|
IvfflatUpdateList(index, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|