mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Replace linear searches with binary searches in pg_dump's code to
lookup objects by OID. Per gripe from nikitathespider.
This commit is contained in:
@ -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;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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;
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user