aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gist/gistvacuum.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2006-05-10 09:19:54 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2006-05-10 09:19:54 +0000
commit10dd8df68e6c826186b9900b703051b46ccd6b31 (patch)
tree3fc1063bedf9bb467c87ad204fd8b68805402404 /src/backend/access/gist/gistvacuum.c
parent12049d343e1aba53b74c68d3f739707343a5e301 (diff)
downloadpostgresql-10dd8df68e6c826186b9900b703051b46ccd6b31.tar.gz
postgresql-10dd8df68e6c826186b9900b703051b46ccd6b31.zip
Reduce size of critical section and remove call of user-defined functions in
insertion and deletion, modify gistSplit() to do not use buffers. TODO: gistvacuumcleanup and XLOG
Diffstat (limited to 'src/backend/access/gist/gistvacuum.c')
-rw-r--r--src/backend/access/gist/gistvacuum.c83
1 files changed, 49 insertions, 34 deletions
diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c
index eafd472c5fd..e81c0ebf487 100644
--- a/src/backend/access/gist/gistvacuum.c
+++ b/src/backend/access/gist/gistvacuum.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.19 2006/05/02 22:25:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.20 2006/05/10 09:19:54 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -85,10 +85,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (GistPageIsLeaf(page))
{
if (GistTuplesDeleted(page))
- {
needunion = needwrite = true;
- GistClearTuplesDeleted(page);
- }
}
else
{
@@ -157,30 +154,54 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (curlenaddon)
{
/* insert updated tuples */
- if (gistnospace(page, addon, curlenaddon))
+ if (gistnospace(page, addon, curlenaddon, InvalidOffsetNumber))
{
/* there is no space on page to insert tuples */
IndexTuple *vec;
SplitedPageLayout *dist = NULL,
*ptr;
- int i;
+ int i, veclen=0;
MemoryContext oldCtx = MemoryContextSwitchTo(gv->opCtx);
- vec = gistextractbuffer(buffer, &(res.ituplen));
- vec = gistjoinvector(vec, &(res.ituplen), addon, curlenaddon);
- res.itup = gistSplit(gv->index, buffer, vec, &(res.ituplen), &dist, &(gv->giststate));
+ vec = gistextractbuffer(buffer, &veclen);
+ vec = gistjoinvector(vec, &veclen, addon, curlenaddon);
+ dist = gistSplit(gv->index, page, vec, veclen, &(gv->giststate));
+
MemoryContextSwitchTo(oldCtx);
- vec = (IndexTuple *) palloc(sizeof(IndexTuple) * res.ituplen);
- for (i = 0; i < res.ituplen; i++)
- {
- vec[i] = (IndexTuple) palloc(IndexTupleSize(res.itup[i]));
- memcpy(vec[i], res.itup[i], IndexTupleSize(res.itup[i]));
+ if (blkno != GIST_ROOT_BLKNO) {
+ /* if non-root split then we should not allocate new buffer */
+ dist->buffer = buffer;
+ dist->page = BufferGetPage(dist->buffer);
+ GistPageGetOpaque(dist->page)->flags = 0;
}
- res.itup = vec;
- for (ptr = dist; ptr; ptr = ptr->next)
- {
+ res.itup = (IndexTuple *) palloc(sizeof(IndexTuple) * veclen);
+ res.ituplen = 0;
+
+ /* make new pages and fills them */
+ for (ptr = dist; ptr; ptr = ptr->next) {
+ char *data;
+
+ if ( ptr->buffer == InvalidBuffer ) {
+ ptr->buffer = gistNewBuffer( gv->index );
+ GISTInitBuffer( ptr->buffer, 0 );
+ ptr->page = BufferGetPage(ptr->buffer);
+ }
+ ptr->block.blkno = BufferGetBlockNumber( ptr->buffer );
+
+ data = (char*)(ptr->list);
+ for(i=0;i<ptr->block.num;i++) {
+ if ( PageAddItem(ptr->page, (Item)data, IndexTupleSize((IndexTuple)data), i+FirstOffsetNumber, LP_USED) == InvalidOffsetNumber )
+ elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(gv->index));
+ data += IndexTupleSize((IndexTuple)data);
+ }
+
+ ItemPointerSetBlockNumber(&(ptr->itup->t_tid), ptr->block.blkno);
+ res.itup[ res.ituplen ] = (IndexTuple)palloc(IndexTupleSize(ptr->itup));
+ memcpy( res.itup[ res.ituplen ], ptr->itup, IndexTupleSize(ptr->itup) );
+ res.ituplen++;
+
MarkBufferDirty(ptr->buffer);
}
@@ -218,10 +239,9 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
for (ptr = dist; ptr; ptr = ptr->next)
{
- /* we must keep the buffer lock on the head page */
+ /* we must keep the buffer pin on the head page */
if (BufferGetBlockNumber(ptr->buffer) != blkno)
- LockBuffer(ptr->buffer, GIST_UNLOCK);
- ReleaseBuffer(ptr->buffer);
+ UnlockReleaseBuffer( ptr->buffer );
}
if (blkno == GIST_ROOT_BLKNO)
@@ -294,6 +314,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (needwrite)
{
MarkBufferDirty(buffer);
+ GistClearTuplesDeleted(page);
if (!gv->index->rd_istemp)
{
@@ -570,14 +591,7 @@ gistbulkdelete(PG_FUNCTION_ARGS)
/*
* Remove deletable tuples from page
- *
- * XXX try to make this critical section shorter. Could do it
- * by separating the callback loop from the actual tuple deletion,
- * but that would affect the definition of the todelete[] array
- * passed into the WAL record (because the indexes would all be
- * pre-deletion).
*/
- START_CRIT_SECTION();
maxoff = PageGetMaxOffsetNumber(page);
@@ -588,13 +602,9 @@ gistbulkdelete(PG_FUNCTION_ARGS)
if (callback(&(idxtuple->t_tid), callback_state))
{
- PageIndexTupleDelete(page, i);
- todelete[ntodelete] = i;
- i--;
- maxoff--;
+ todelete[ntodelete] = i-ntodelete;
ntodelete++;
stats->std.tuples_removed += 1;
- Assert(maxoff == PageGetMaxOffsetNumber(page));
}
else
stats->std.num_index_tuples += 1;
@@ -602,10 +612,14 @@ gistbulkdelete(PG_FUNCTION_ARGS)
if (ntodelete)
{
- GistMarkTuplesDeleted(page);
+ START_CRIT_SECTION();
MarkBufferDirty(buffer);
+ for(i=0;i<ntodelete;i++)
+ PageIndexTupleDelete(page, todelete[i]);
+ GistMarkTuplesDeleted(page);
+
if (!rel->rd_istemp)
{
XLogRecData *rdata;
@@ -627,9 +641,10 @@ gistbulkdelete(PG_FUNCTION_ARGS)
}
else
PageSetLSN(page, XLogRecPtrForTemp);
+
+ END_CRIT_SECTION();
}
- END_CRIT_SECTION();
}
else
{