Add GiST metabuffer.
authorRobert Haas <rhaas@postgresql.org>
Sun, 10 Jun 2012 12:47:32 +0000 (08:47 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 14 Jun 2012 14:33:04 +0000 (10:33 -0400)
src/backend/access/gist/gistbuild.c

index 9d68afb64fa76acd1c73b40ca6ecd41b9839fcc2..5006577efcf0d231d8c9b00a7e4c4606dda48b3d 100644 (file)
@@ -73,6 +73,7 @@ typedef struct
 } GISTBuildState;
 
 /* prototypes for private functions */
+static void GistInitMetabuffer(Relation index, Buffer buffer, BlockNumber root);
 static void gistInitBuffering(GISTBuildState *buildstate);
 static int     calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep);
 static void gistBuildCallback(Relation index,
@@ -117,8 +118,11 @@ gistbuild(PG_FUNCTION_ARGS)
        IndexBuildResult *result;
        double          reltuples;
        GISTBuildState buildstate;
-       Buffer          rootbuffer;
-       Page            rootpage;
+       Buffer          metabuffer,
+                               rootbuffer;
+       Page            metapage,
+                               rootpage;
+       BlockNumber     rootblock;
        MemoryContext oldcxt = CurrentMemoryContext;
        int                     fillfactor;
 
@@ -178,12 +182,17 @@ gistbuild(PG_FUNCTION_ARGS)
         */
        buildstate.giststate->tempCxt = createTempGistContext();
 
-       /* initialize the root page */
+       /* initialize the metabuffer and root buffer */
+       metabuffer = gistNewBuffer(index);
+       metapage = BufferGetPage(metabuffer);
+       Assert(BufferGetBlockNumber(metabuffer) == GIST_METAPAGE_BLKNO);
        rootbuffer = gistNewBuffer(index);
        rootpage = BufferGetPage(rootbuffer);
+       rootblock = BufferGetBlockNumber(rootbuffer);
 
        START_CRIT_SECTION();
 
+       GistInitMetabuffer(index, metabuffer, rootblock);
        GISTInitBuffer(rootbuffer, F_LEAF | F_ROOT);
 
        MarkBufferDirty(rootbuffer);
@@ -195,7 +204,7 @@ gistbuild(PG_FUNCTION_ARGS)
                gistxlogCreateIndex     xlrec;
 
                xlrec.node = index->rd_node;
-               xlrec.blkno = BufferGetBlockNumber(rootbuffer);
+               xlrec.blkno = rootblock;
 
                rdata.data = (char *) &xlrec;
                rdata.len = sizeof(RelFileNode);
@@ -210,6 +219,7 @@ gistbuild(PG_FUNCTION_ARGS)
                PageSetLSN(rootpage, GetXLogRecPtrForTemp());
 
        UnlockReleaseBuffer(rootbuffer);
+       UnlockReleaseBuffer(metabuffer);
 
        END_CRIT_SECTION();
 
@@ -251,6 +261,24 @@ gistbuild(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+/*
+ * Initialize metabuffer.
+ */
+static void
+GistInitMetabuffer(Relation index, Buffer buffer, BlockNumber root)
+{
+       GistMetaPageData   *meta;
+       Page            page = BufferGetPage(buffer);
+
+       GISTInitBuffer(buffer, 0);
+       MetapageInit(index, page);
+
+       meta = GistPageGetMeta(page);
+       meta->gist_magic = GIST_MAGIC;
+       meta->gist_version = GIST_VERSION;
+       meta->gist_root = root;
+}
+
 /*
  * Validator for "buffering" reloption on GiST indexes. Allows "on", "off"
  * and "auto" values.