|
|||||||||||
|
Re: [GENERAL] 5 minutes to pg_dump nothing
From: Tom Lane <tgl(at)sss.pgh.pa.us>
Date: Sun Sep 23 2007 - 19:42:45 EDT
> "Nikita The Spider The Spider" > We might look into fixing it for 8.3, but I doubt we'd risk back-patching > such a change to older branches. Actually, it doesn't look that hard --- want to try the attached patch? I couldn't measure any speed difference at all on the standard PG regression-test database, but there are not huge numbers of objects in that. regards, tom lane Index: common.c RCS file: /cvsroot/pgsql/src/bin/pg_dump/common.c,v retrieving revision 1.97 diff -c -r1.97 common.c *** common.c 21 Aug 2007 01:11:20 -0000 1.97 --- common.c 23 Sep 2007 23:37:32 -0000
/* * These variables are static to avoid the notational cruft of having to pass ! * them into findTableByOid() and friends. */ static TableInfo *tblinfo; static TypeInfo *typinfo; --- 41,51 ---- /* * These variables are static to avoid the notational cruft of having to pass ! * them into findTableByOid() and friends. For each of these arrays, we ! * build a sorted-by-OID index array immediately after it's built, and then ! * we use binary search in findTableByOid() and friends. (qsort'ing the base ! * arrays themselves would be simpler, but it doesn't work because pg_dump.c ! * may have already established pointers between items.) */ static TableInfo *tblinfo; static TypeInfo *typinfo;
static void flagInhTables(TableInfo *tbinfo, int numTables, InhInfo *inhinfo, int numInherits); static void flagInhAttrs(TableInfo *tbinfo, int numTables, InhInfo *inhinfo, int numInherits); + static DumpableObject **buildIndexArray(void *objArray, int numObjs, + Size objSize); static int DOCatalogIdCompare(const void *p1, const void *p2); static void findParentsByOid(TableInfo *self, InhInfo *inhinfo, int numInherits);
/* this must be after getFuncs */ if (g_verbose) write_msg(NULL, "reading user-defined types\n"); typinfo = getTypes(&numTypes); + typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo)); /* this must be after getFuncs, too */ if (g_verbose)
if (g_verbose) write_msg(NULL, "reading user-defined operator classes\n");
if (g_verbose) write_msg(NULL, "reading table inheritance information\n");
+ /*
+ * Find a DumpableObject by OID, in a pre-sorted array of one type of object
+ *
+ * Returns NULL for unknown OID
+ */
+ static DumpableObject *
+ findObjectByOid(Oid oid, DumpableObject **indexArray, int numObjs)
+ {
+ DumpableObject **low;
+ DumpableObject **high;
+
+ /*
+ * This is the same as findObjectByCatalogId except we assume we need
+ * not look at table OID because the objects are all the same type.
+ *
+ * We could use bsearch() here, but the notational cruft of calling
+ * bsearch is nearly as bad as doing it ourselves; and the generalized
+ * bsearch function is noticeably slower as well.
+ */
+ if (numObjs <= 0)
+ return NULL;
+ low = indexArray;
+ high = indexArray + (numObjs - 1);
+ while (low <= high)
+ {
+ DumpableObject **middle;
+ int difference;
+
+ middle = low + (high - low) / 2;
+ difference = oidcmp((*middle)->catId.oid, oid);
+ if (difference == 0)
+ return *middle;
+ else if (difference < 0)
+ low = middle + 1;
+ else
+ high = middle - 1;
+ }
+ return NULL;
+ }
+
+ /*
+ * Build an index array of DumpableObject pointers, sorted by OID
+ */
+ static DumpableObject **
+ buildIndexArray(void *objArray, int numObjs, Size objSize)
+ {
+ DumpableObject **ptrs;
+ int i;
+
+ ptrs = (DumpableObject **) malloc(numObjs * sizeof(DumpableObject *));
+ for (i = 0; i < numObjs; i++)
+ ptrs[i] = (DumpableObject *) ((char *) objArray + i * objSize);
+
+ /* We can use DOCatalogIdCompare to sort since its first key is OID */
+ if (numObjs > 1)
+ qsort((void *) ptrs, numObjs, sizeof(DumpableObject *),
+ DOCatalogIdCompare);
+
+ return ptrs;
+ }
+
+ /*
+ * qsort comparator for pointers to DumpableObjects
+ */
static int DOCatalogIdCompare(const void *p1, const void *p2) {
/* * findTypeByOid * finds the entry (in typinfo) of the type with the given oid * returns NULL if not found - * - * NOTE: should hash this, but just do linear search for now */ TypeInfo * findTypeByOid(Oid oid) {
! int i;
!
! for (i = 0; i < numTypes; i++)
! {
! if (typinfo[i].dobj.catId.oid == oid)
! return &typinfo[i];
! }
! return NULL;
} /* * findFuncByOid * finds the entry (in funinfo) of the function with the given oid * returns NULL if not found - * - * NOTE: should hash this, but just do linear search for now */ FuncInfo * findFuncByOid(Oid oid) {
! int i;
!
! for (i = 0; i < numFuncs; i++)
! {
! if (funinfo[i].dobj.catId.oid == oid)
! return &funinfo[i];
! }
! return NULL;
} /* * findOprByOid * finds the entry (in oprinfo) of the operator with the given oid * returns NULL if not found - * - * NOTE: should hash this, but just do linear search for now */ OprInfo * findOprByOid(Oid oid) {
! int i;
!
! for (i = 0; i < numOperators; i++)
! {
! if (oprinfo[i].dobj.catId.oid == oid)
! return &oprinfo[i];
! }
! return NULL;
}
/* * findTypeByOid * finds the entry (in typinfo) of the type with the given oid * returns NULL if not found */ TypeInfo * findTypeByOid(Oid oid) { ! return (TypeInfo *) findObjectByOid(oid, typinfoindex, numTypes); } /* * findFuncByOid * finds the entry (in funinfo) of the function with the given oid * returns NULL if not found */ FuncInfo * findFuncByOid(Oid oid) { ! return (FuncInfo *) findObjectByOid(oid, funinfoindex, numFuncs); } /* * findOprByOid * finds the entry (in oprinfo) of the operator with the given oid * returns NULL if not found */ OprInfo * findOprByOid(Oid oid) { ! return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators); } ---------------------------(end of broadcast)---------------------------TIP 2: Don't 'kill -9' the postmaster Received on Sun Sep 23 19:46:28 2007 This archive was generated by hypermail 2.1.8 : Sun Oct 07 2007 - 11:47:31 EDT |
||||||||||
|
|||||||||||