Commit 7bb11a93 authored by Tom Lane's avatar Tom Lane

Speed up findObjectByCatalogId() to get rid of the other salient

bottleneck in the new pg_dump code.
parent f8495a6b
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.78 2003/12/06 03:00:11 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.79 2003/12/07 03:14:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -37,6 +37,13 @@ static DumpableObject **dumpIdMap = NULL;
static int allocedDumpIds = 0;
static DumpId lastDumpId = 0;
/*
* Variables for mapping CatalogId to DumpableObject
*/
static bool catalogIdMapValid = false;
static DumpableObject **catalogIdMap = NULL;
static int numCatalogIds = 0;
/*
* These variables are static to avoid the notational cruft of having to pass
* them into findTableByOid() and friends.
......@@ -51,12 +58,13 @@ static int numFuncs;
static int numOperators;
static void findParentsByOid(TableInfo *self,
InhInfo *inhinfo, int numInherits);
static void flagInhTables(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits);
static void flagInhAttrs(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits);
static int DOCatalogIdCompare(const void *p1, const void *p2);
static void findParentsByOid(TableInfo *self,
InhInfo *inhinfo, int numInherits);
static int strInArray(const char *pattern, char **arr, int arr_size);
......@@ -413,6 +421,9 @@ AssignDumpId(DumpableObject *dobj)
allocedDumpIds = newAlloc;
}
dumpIdMap[dobj->dumpId] = dobj;
/* mark catalogIdMap invalid, but don't rebuild it yet */
catalogIdMapValid = false;
}
/*
......@@ -454,25 +465,74 @@ findObjectByDumpId(DumpId dumpId)
*
* Returns NULL for unknown ID
*
* NOTE: should hash this, but just do linear search for now
* We use binary search in a sorted list that is built on first call.
* If AssignDumpId() and findObjectByCatalogId() calls were intermixed,
* the code would work, but possibly be very slow. In the current usage
* pattern that does not happen, indeed we only need to build the list once.
*/
DumpableObject *
findObjectByCatalogId(CatalogId catalogId)
{
DumpId i;
DumpableObject **low;
DumpableObject **high;
for (i = 1; i < allocedDumpIds; i++)
if (!catalogIdMapValid)
{
DumpableObject *dobj = dumpIdMap[i];
if (catalogIdMap)
free(catalogIdMap);
getDumpableObjects(&catalogIdMap, &numCatalogIds);
if (numCatalogIds > 1)
qsort((void *) catalogIdMap, numCatalogIds,
sizeof(DumpableObject *), DOCatalogIdCompare);
catalogIdMapValid = true;
}
if (dobj &&
dobj->catId.tableoid == catalogId.tableoid &&
dobj->catId.oid == catalogId.oid)
return dobj;
/*
* 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 (numCatalogIds <= 0)
return NULL;
low = catalogIdMap;
high = catalogIdMap + (numCatalogIds - 1);
while (low <= high)
{
DumpableObject **middle;
int difference;
middle = low + (high - low) / 2;
/* comparison must match DOCatalogIdCompare, below */
difference = oidcmp((*middle)->catId.oid, catalogId.oid);
if (difference == 0)
difference = oidcmp((*middle)->catId.tableoid, catalogId.tableoid);
if (difference == 0)
return *middle;
else if (difference < 0)
low = middle + 1;
else
high = middle - 1;
}
return NULL;
}
static int
DOCatalogIdCompare(const void *p1, const void *p2)
{
DumpableObject *obj1 = *(DumpableObject **) p1;
DumpableObject *obj2 = *(DumpableObject **) p2;
int cmpval;
/*
* Compare OID first since it's usually unique, whereas there will
* only be a few distinct values of tableoid.
*/
cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid);
if (cmpval == 0)
cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid);
return cmpval;
}
/*
* Build an array of pointers to all known dumpable objects
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment