refactor index build - Mailing list pgsql-patches

From Neil Conway
Subject refactor index build
Date
Msg-id 42816EE4.4070409@samurai.com
Whole thread Raw
Responses Re: refactor index build  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
This patch refactors away some duplicated code in the index AM build
methods: they all invoke UpdateStats() since they have computed the
number of heap tuples, so I created a function in catalog/index.c that
each AM calls. This is per earlier discussion (it was included in the
GiST patches I submitted a while back, but I'm breaking those patches up
into smaller chunks now).

Barring any objections, I'll apply this later today or tomorrow.

-Neil
Index: src/backend/access/gist/gist.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/access/gist/gist.c,v
retrieving revision 1.113
diff -c -r1.113 gist.c
*** src/backend/access/gist/gist.c    21 Mar 2005 01:23:56 -0000    1.113
--- src/backend/access/gist/gist.c    11 May 2005 02:27:22 -0000
***************
*** 184,210 ****

      /* okay, all heap tuples are indexed */

!     /*
!      * Since we just counted the tuples in the heap, we update its stats
!      * in pg_class to guarantee that the planner takes advantage of the
!      * index we just created.  But, only update statistics during normal
!      * index definitions, not for indices on system catalogs created
!      * during bootstrap processing.  We must close the relations before
!      * updating statistics to guarantee that the relcache entries are
!      * flushed when we increment the command counter in UpdateStats(). But
!      * we do not release any locks on the relations; those will be held
!      * until end of transaction.
!      */
!     if (IsNormalProcessingMode())
!     {
!         Oid            hrelid = RelationGetRelid(heap);
!         Oid            irelid = RelationGetRelid(index);
!
!         heap_close(heap, NoLock);
!         index_close(index);
!         UpdateStats(hrelid, reltuples);
!         UpdateStats(irelid, buildstate.indtuples);
!     }

      freeGISTstate(&buildstate.giststate);
  #ifdef GISTDEBUG
--- 184,191 ----

      /* okay, all heap tuples are indexed */

!     /* since we just counted the # of tuples, may as well update stats */
!     IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples);

      freeGISTstate(&buildstate.giststate);
  #ifdef GISTDEBUG
Index: src/backend/access/hash/hash.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/access/hash/hash.c,v
retrieving revision 1.78
diff -c -r1.78 hash.c
*** src/backend/access/hash/hash.c    27 Mar 2005 23:52:57 -0000    1.78
--- src/backend/access/hash/hash.c    11 May 2005 02:27:30 -0000
***************
*** 72,98 ****
      reltuples = IndexBuildHeapScan(heap, index, indexInfo,
                                  hashbuildCallback, (void *) &buildstate);

!     /*
!      * Since we just counted the tuples in the heap, we update its stats
!      * in pg_class to guarantee that the planner takes advantage of the
!      * index we just created.  But, only update statistics during normal
!      * index definitions, not for indices on system catalogs created
!      * during bootstrap processing.  We must close the relations before
!      * updating statistics to guarantee that the relcache entries are
!      * flushed when we increment the command counter in UpdateStats(). But
!      * we do not release any locks on the relations; those will be held
!      * until end of transaction.
!      */
!     if (IsNormalProcessingMode())
!     {
!         Oid            hrelid = RelationGetRelid(heap);
!         Oid            irelid = RelationGetRelid(index);
!
!         heap_close(heap, NoLock);
!         index_close(index);
!         UpdateStats(hrelid, reltuples);
!         UpdateStats(irelid, buildstate.indtuples);
!     }

      PG_RETURN_VOID();
  }
--- 72,79 ----
      reltuples = IndexBuildHeapScan(heap, index, indexInfo,
                                  hashbuildCallback, (void *) &buildstate);

!     /* since we just counted the # of tuples, may as well update stats */
!     IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples);

      PG_RETURN_VOID();
  }
Index: src/backend/access/nbtree/nbtree.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/access/nbtree/nbtree.c,v
retrieving revision 1.129
diff -c -r1.129 nbtree.c
*** src/backend/access/nbtree/nbtree.c    7 May 2005 21:32:23 -0000    1.129
--- src/backend/access/nbtree/nbtree.c    11 May 2005 02:27:40 -0000
***************
*** 148,174 ****
      }
  #endif   /* BTREE_BUILD_STATS */

!     /*
!      * Since we just counted the tuples in the heap, we update its stats
!      * in pg_class to guarantee that the planner takes advantage of the
!      * index we just created.  But, only update statistics during normal
!      * index definitions, not for indices on system catalogs created
!      * during bootstrap processing.  We must close the relations before
!      * updating statistics to guarantee that the relcache entries are
!      * flushed when we increment the command counter in UpdateStats(). But
!      * we do not release any locks on the relations; those will be held
!      * until end of transaction.
!      */
!     if (IsNormalProcessingMode())
!     {
!         Oid            hrelid = RelationGetRelid(heap);
!         Oid            irelid = RelationGetRelid(index);
!
!         heap_close(heap, NoLock);
!         index_close(index);
!         UpdateStats(hrelid, reltuples);
!         UpdateStats(irelid, buildstate.indtuples);
!     }

      PG_RETURN_VOID();
  }
--- 148,155 ----
      }
  #endif   /* BTREE_BUILD_STATS */

!     /* since we just counted the # of tuples, may as well update stats */
!     IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples);

      PG_RETURN_VOID();
  }
Index: src/backend/access/rtree/rtree.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/access/rtree/rtree.c,v
retrieving revision 1.88
diff -c -r1.88 rtree.c
*** src/backend/access/rtree/rtree.c    21 Mar 2005 01:24:00 -0000    1.88
--- src/backend/access/rtree/rtree.c    11 May 2005 02:27:47 -0000
***************
*** 142,168 ****

      /* okay, all heap tuples are indexed */

!     /*
!      * Since we just counted the tuples in the heap, we update its stats
!      * in pg_class to guarantee that the planner takes advantage of the
!      * index we just created.  But, only update statistics during normal
!      * index definitions, not for indices on system catalogs created
!      * during bootstrap processing.  We must close the relations before
!      * updating statistics to guarantee that the relcache entries are
!      * flushed when we increment the command counter in UpdateStats(). But
!      * we do not release any locks on the relations; those will be held
!      * until end of transaction.
!      */
!     if (IsNormalProcessingMode())
!     {
!         Oid            hrelid = RelationGetRelid(heap);
!         Oid            irelid = RelationGetRelid(index);
!
!         heap_close(heap, NoLock);
!         index_close(index);
!         UpdateStats(hrelid, reltuples);
!         UpdateStats(irelid, buildstate.indtuples);
!     }

      PG_RETURN_VOID();
  }
--- 142,149 ----

      /* okay, all heap tuples are indexed */

!     /* since we just counted the # of tuples, may as well update stats */
!     IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples);

      PG_RETURN_VOID();
  }
Index: src/backend/catalog/index.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.254
diff -c -r1.254 index.c
*** src/backend/catalog/index.c    6 May 2005 17:24:52 -0000    1.254
--- src/backend/catalog/index.c    11 May 2005 02:09:55 -0000
***************
*** 62,67 ****
--- 62,68 ----
                      Oid *classOids,
                      bool primary);
  static Oid    IndexGetRelation(Oid indexId);
+ static void UpdateStats(Oid relid, double reltuples);


  /*
***************
*** 1149,1154 ****
--- 1150,1185 ----
  }


+ /*
+  * This is invoked by the various index AMs once they have finished
+  * constructing an index. Constructing an index involves counting the
+  * number of tuples in both the relation and the index, so we take
+  * advantage of the opportunity to update pg_class to ensure that the
+  * planner takes advantage of the index we just created.  But, only
+  * update statistics during normal index definitions, not for indices
+  * on system catalogs created during bootstrap processing.  We must
+  * close the relations before updating statistics to guarantee that
+  * the relcache entries are flushed when we increment the command
+  * counter in UpdateStats(). But we do not release any locks on the
+  * relations; those will be held until end of transaction.
+  */
+ void
+ IndexCloseAndUpdateStats(Relation heap, double heapTuples,
+                          Relation index, double indexTuples)
+ {
+     Oid        hrelid = RelationGetRelid(heap);
+     Oid        irelid = RelationGetRelid(index);
+
+     if (!IsNormalProcessingMode())
+         return;
+
+     heap_close(heap, NoLock);
+     index_close(index);
+     UpdateStats(hrelid, heapTuples);
+     UpdateStats(irelid, indexTuples);
+ }
+
+
  /* ----------------
   *        UpdateStats
   *
***************
*** 1157,1163 ****
   * in the context of VACUUM, only CREATE INDEX.
   * ----------------
   */
! void
  UpdateStats(Oid relid, double reltuples)
  {
      Relation    whichRel;
--- 1188,1194 ----
   * in the context of VACUUM, only CREATE INDEX.
   * ----------------
   */
! static void
  UpdateStats(Oid relid, double reltuples)
  {
      Relation    whichRel;
Index: src/include/catalog/index.h
===================================================================
RCS file: /var/lib/cvs/pgsql/src/include/catalog/index.h,v
retrieving revision 1.62
diff -c -r1.62 index.h
*** src/include/catalog/index.h    14 Apr 2005 01:38:20 -0000    1.62
--- src/include/catalog/index.h    11 May 2005 02:24:28 -0000
***************
*** 52,58 ****
                 Datum *values,
                 bool *isnull);

! extern void UpdateStats(Oid relid, double reltuples);

  extern void setRelhasindex(Oid relid, bool hasindex,
                 bool isprimary, Oid reltoastidxid);
--- 52,59 ----
                 Datum *values,
                 bool *isnull);

! extern void IndexCloseAndUpdateStats(Relation heap, double heapTuples,
!                                      Relation index, double indexTuples);

  extern void setRelhasindex(Oid relid, bool hasindex,
                 bool isprimary, Oid reltoastidxid);

pgsql-patches by date:

Previous
From: Christopher Kings-Lynne
Date:
Subject: Re: lastval()
Next
From: Abhijit Menon-Sen
Date:
Subject: Re: lastval()