mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
Use binary search instead of brute-force scan in findNamespace().
The previous coding presented a significant bottleneck when dumping databases containing many thousands of schemas, since the total time spent searching would increase roughly as O(N^2) in the number of objects. Noted by Jeff Janes, though I rewrote his proposed patch to use the existing findObjectByOid infrastructure. Since this is a longstanding performance bug, backpatch to all supported versions.
This commit is contained in:
parent
45ca31d6a7
commit
73cc7d3b24
@ -48,16 +48,19 @@ static TableInfo *tblinfo;
|
||||
static TypeInfo *typinfo;
|
||||
static FuncInfo *funinfo;
|
||||
static OprInfo *oprinfo;
|
||||
static NamespaceInfo *nspinfo;
|
||||
static int numTables;
|
||||
static int numTypes;
|
||||
static int numFuncs;
|
||||
static int numOperators;
|
||||
static int numCollations;
|
||||
static int numNamespaces;
|
||||
static DumpableObject **tblinfoindex;
|
||||
static DumpableObject **typinfoindex;
|
||||
static DumpableObject **funinfoindex;
|
||||
static DumpableObject **oprinfoindex;
|
||||
static DumpableObject **collinfoindex;
|
||||
static DumpableObject **nspinfoindex;
|
||||
|
||||
|
||||
static void flagInhTables(TableInfo *tbinfo, int numTables,
|
||||
@ -81,7 +84,6 @@ getSchemaData(Archive *fout, int *numTablesPtr)
|
||||
ExtensionInfo *extinfo;
|
||||
InhInfo *inhinfo;
|
||||
CollInfo *collinfo;
|
||||
int numNamespaces;
|
||||
int numExtensions;
|
||||
int numAggregates;
|
||||
int numInherits;
|
||||
@ -101,7 +103,8 @@ getSchemaData(Archive *fout, int *numTablesPtr)
|
||||
|
||||
if (g_verbose)
|
||||
write_msg(NULL, "reading schemas\n");
|
||||
getNamespaces(fout, &numNamespaces);
|
||||
nspinfo = getNamespaces(fout, &numNamespaces);
|
||||
nspinfoindex = buildIndexArray(nspinfo, numNamespaces, sizeof(NamespaceInfo));
|
||||
|
||||
/*
|
||||
* getTables should be done as soon as possible, so as to minimize the
|
||||
@ -732,6 +735,17 @@ findCollationByOid(Oid oid)
|
||||
return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations);
|
||||
}
|
||||
|
||||
/*
|
||||
* findNamespaceByOid
|
||||
* finds the entry (in nspinfo) of the namespace with the given oid
|
||||
* returns NULL if not found
|
||||
*/
|
||||
NamespaceInfo *
|
||||
findNamespaceByOid(Oid oid)
|
||||
{
|
||||
return (NamespaceInfo *) findObjectByOid(oid, nspinfoindex, numNamespaces);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* findParentsByOid
|
||||
|
@ -129,10 +129,6 @@ char g_comment_end[10];
|
||||
|
||||
static const CatalogId nilCatalogId = {0, 0};
|
||||
|
||||
/* these are to avoid passing around info for findNamespace() */
|
||||
static NamespaceInfo *g_namespaces;
|
||||
static int g_numNamespaces;
|
||||
|
||||
/* flags for various command-line long options */
|
||||
static int binary_upgrade = 0;
|
||||
static int disable_dollar_quoting = 0;
|
||||
@ -2595,8 +2591,7 @@ getNamespaces(Archive *fout, int *numNamespaces)
|
||||
|
||||
selectDumpableNamespace(&nsinfo[1]);
|
||||
|
||||
g_namespaces = nsinfo;
|
||||
g_numNamespaces = *numNamespaces = 2;
|
||||
*numNamespaces = 2;
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
@ -2648,8 +2643,7 @@ getNamespaces(Archive *fout, int *numNamespaces)
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
|
||||
g_namespaces = nsinfo;
|
||||
g_numNamespaces = *numNamespaces = ntups;
|
||||
*numNamespaces = ntups;
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
@ -2660,35 +2654,34 @@ getNamespaces(Archive *fout, int *numNamespaces)
|
||||
* getNamespaces
|
||||
*
|
||||
* NB: for pre-7.3 source database, we use object OID to guess whether it's
|
||||
* a system object or not. In 7.3 and later there is no guessing.
|
||||
* a system object or not. In 7.3 and later there is no guessing, and we
|
||||
* don't use objoid at all.
|
||||
*/
|
||||
static NamespaceInfo *
|
||||
findNamespace(Archive *fout, Oid nsoid, Oid objoid)
|
||||
{
|
||||
int i;
|
||||
NamespaceInfo *nsinfo;
|
||||
|
||||
if (fout->remoteVersion >= 70300)
|
||||
{
|
||||
for (i = 0; i < g_numNamespaces; i++)
|
||||
{
|
||||
NamespaceInfo *nsinfo = &g_namespaces[i];
|
||||
|
||||
if (nsoid == nsinfo->dobj.catId.oid)
|
||||
return nsinfo;
|
||||
}
|
||||
exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid);
|
||||
nsinfo = findNamespaceByOid(nsoid);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This code depends on the layout set up by getNamespaces. */
|
||||
/* This code depends on the dummy objects set up by getNamespaces. */
|
||||
Oid i;
|
||||
|
||||
if (objoid > g_last_builtin_oid)
|
||||
i = 0; /* user object */
|
||||
else
|
||||
i = 1; /* system object */
|
||||
return &g_namespaces[i];
|
||||
nsinfo = findNamespaceByOid(i);
|
||||
}
|
||||
|
||||
return NULL; /* keep compiler quiet */
|
||||
if (nsinfo == NULL)
|
||||
exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid);
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -511,6 +511,7 @@ extern TypeInfo *findTypeByOid(Oid oid);
|
||||
extern FuncInfo *findFuncByOid(Oid oid);
|
||||
extern OprInfo *findOprByOid(Oid oid);
|
||||
extern CollInfo *findCollationByOid(Oid oid);
|
||||
extern NamespaceInfo *findNamespaceByOid(Oid oid);
|
||||
|
||||
extern void simple_oid_list_append(SimpleOidList *list, Oid val);
|
||||
extern void simple_string_list_append(SimpleStringList *list, const char *val);
|
||||
|
Loading…
Reference in New Issue
Block a user