Commit c3b193a5 authored by Tom Lane's avatar Tom Lane

Replace linear searches with binary searches in pg_dump's code to

lookup objects by OID.  Per gripe from nikitathespider.
parent aabb7000
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.97 2007/08/21 01:11:20 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.98 2007/09/23 23:39:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -41,7 +41,11 @@ static int numCatalogIds = 0; ...@@ -41,7 +41,11 @@ static int numCatalogIds = 0;
/* /*
* These variables are static to avoid the notational cruft of having to pass * These variables are static to avoid the notational cruft of having to pass
* them into findTableByOid() and friends. * 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 TableInfo *tblinfo;
static TypeInfo *typinfo; static TypeInfo *typinfo;
...@@ -51,12 +55,18 @@ static int numTables; ...@@ -51,12 +55,18 @@ static int numTables;
static int numTypes; static int numTypes;
static int numFuncs; static int numFuncs;
static int numOperators; static int numOperators;
static DumpableObject **tblinfoindex;
static DumpableObject **typinfoindex;
static DumpableObject **funinfoindex;
static DumpableObject **oprinfoindex;
static void flagInhTables(TableInfo *tbinfo, int numTables, static void flagInhTables(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits); InhInfo *inhinfo, int numInherits);
static void flagInhAttrs(TableInfo *tbinfo, int numTables, static void flagInhAttrs(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits); InhInfo *inhinfo, int numInherits);
static DumpableObject **buildIndexArray(void *objArray, int numObjs,
Size objSize);
static int DOCatalogIdCompare(const void *p1, const void *p2); static int DOCatalogIdCompare(const void *p1, const void *p2);
static void findParentsByOid(TableInfo *self, static void findParentsByOid(TableInfo *self,
InhInfo *inhinfo, int numInherits); InhInfo *inhinfo, int numInherits);
...@@ -104,11 +114,13 @@ getSchemaData(int *numTablesPtr) ...@@ -104,11 +114,13 @@ getSchemaData(int *numTablesPtr)
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading user-defined functions\n"); write_msg(NULL, "reading user-defined functions\n");
funinfo = getFuncs(&numFuncs); funinfo = getFuncs(&numFuncs);
funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo));
/* this must be after getFuncs */ /* this must be after getFuncs */
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading user-defined types\n"); write_msg(NULL, "reading user-defined types\n");
typinfo = getTypes(&numTypes); typinfo = getTypes(&numTypes);
typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo));
/* this must be after getFuncs, too */ /* this must be after getFuncs, too */
if (g_verbose) if (g_verbose)
...@@ -122,6 +134,7 @@ getSchemaData(int *numTablesPtr) ...@@ -122,6 +134,7 @@ getSchemaData(int *numTablesPtr)
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading user-defined operators\n"); write_msg(NULL, "reading user-defined operators\n");
oprinfo = getOperators(&numOperators); oprinfo = getOperators(&numOperators);
oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo));
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading user-defined operator classes\n"); write_msg(NULL, "reading user-defined operator classes\n");
...@@ -154,6 +167,7 @@ getSchemaData(int *numTablesPtr) ...@@ -154,6 +167,7 @@ getSchemaData(int *numTablesPtr)
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading user-defined tables\n"); write_msg(NULL, "reading user-defined tables\n");
tblinfo = getTables(&numTables); tblinfo = getTables(&numTables);
tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading table inheritance information\n"); write_msg(NULL, "reading table inheritance information\n");
...@@ -540,6 +554,70 @@ findObjectByCatalogId(CatalogId catalogId) ...@@ -540,6 +554,70 @@ findObjectByCatalogId(CatalogId catalogId)
return NULL; return NULL;
} }
/*
* 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 static int
DOCatalogIdCompare(const void *p1, const void *p2) DOCatalogIdCompare(const void *p1, const void *p2)
{ {
...@@ -630,80 +708,44 @@ removeObjectDependency(DumpableObject *dobj, DumpId refId) ...@@ -630,80 +708,44 @@ removeObjectDependency(DumpableObject *dobj, DumpId refId)
* findTableByOid * findTableByOid
* finds the entry (in tblinfo) of the table with the given oid * finds the entry (in tblinfo) of the table with the given oid
* returns NULL if not found * returns NULL if not found
*
* NOTE: should hash this, but just do linear search for now
*/ */
TableInfo * TableInfo *
findTableByOid(Oid oid) findTableByOid(Oid oid)
{ {
int i; return (TableInfo *) findObjectByOid(oid, tblinfoindex, numTables);
for (i = 0; i < numTables; i++)
{
if (tblinfo[i].dobj.catId.oid == oid)
return &tblinfo[i];
}
return NULL;
} }
/* /*
* findTypeByOid * findTypeByOid
* finds the entry (in typinfo) of the type with the given oid * finds the entry (in typinfo) of the type with the given oid
* returns NULL if not found * returns NULL if not found
*
* NOTE: should hash this, but just do linear search for now
*/ */
TypeInfo * TypeInfo *
findTypeByOid(Oid oid) findTypeByOid(Oid oid)
{ {
int i; return (TypeInfo *) findObjectByOid(oid, typinfoindex, numTypes);
for (i = 0; i < numTypes; i++)
{
if (typinfo[i].dobj.catId.oid == oid)
return &typinfo[i];
}
return NULL;
} }
/* /*
* findFuncByOid * findFuncByOid
* finds the entry (in funinfo) of the function with the given oid * finds the entry (in funinfo) of the function with the given oid
* returns NULL if not found * returns NULL if not found
*
* NOTE: should hash this, but just do linear search for now
*/ */
FuncInfo * FuncInfo *
findFuncByOid(Oid oid) findFuncByOid(Oid oid)
{ {
int i; return (FuncInfo *) findObjectByOid(oid, funinfoindex, numFuncs);
for (i = 0; i < numFuncs; i++)
{
if (funinfo[i].dobj.catId.oid == oid)
return &funinfo[i];
}
return NULL;
} }
/* /*
* findOprByOid * findOprByOid
* finds the entry (in oprinfo) of the operator with the given oid * finds the entry (in oprinfo) of the operator with the given oid
* returns NULL if not found * returns NULL if not found
*
* NOTE: should hash this, but just do linear search for now
*/ */
OprInfo * OprInfo *
findOprByOid(Oid oid) findOprByOid(Oid oid)
{ {
int i; return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
for (i = 0; i < numOperators; i++)
{
if (oprinfo[i].dobj.catId.oid == oid)
return &oprinfo[i];
}
return NULL;
} }
......
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