Commit 73cc7d3b authored by Tom Lane's avatar Tom Lane

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.
parent 45ca31d6
...@@ -48,16 +48,19 @@ static TableInfo *tblinfo; ...@@ -48,16 +48,19 @@ static TableInfo *tblinfo;
static TypeInfo *typinfo; static TypeInfo *typinfo;
static FuncInfo *funinfo; static FuncInfo *funinfo;
static OprInfo *oprinfo; static OprInfo *oprinfo;
static NamespaceInfo *nspinfo;
static int numTables; static int numTables;
static int numTypes; static int numTypes;
static int numFuncs; static int numFuncs;
static int numOperators; static int numOperators;
static int numCollations; static int numCollations;
static int numNamespaces;
static DumpableObject **tblinfoindex; static DumpableObject **tblinfoindex;
static DumpableObject **typinfoindex; static DumpableObject **typinfoindex;
static DumpableObject **funinfoindex; static DumpableObject **funinfoindex;
static DumpableObject **oprinfoindex; static DumpableObject **oprinfoindex;
static DumpableObject **collinfoindex; static DumpableObject **collinfoindex;
static DumpableObject **nspinfoindex;
static void flagInhTables(TableInfo *tbinfo, int numTables, static void flagInhTables(TableInfo *tbinfo, int numTables,
...@@ -81,7 +84,6 @@ getSchemaData(Archive *fout, int *numTablesPtr) ...@@ -81,7 +84,6 @@ getSchemaData(Archive *fout, int *numTablesPtr)
ExtensionInfo *extinfo; ExtensionInfo *extinfo;
InhInfo *inhinfo; InhInfo *inhinfo;
CollInfo *collinfo; CollInfo *collinfo;
int numNamespaces;
int numExtensions; int numExtensions;
int numAggregates; int numAggregates;
int numInherits; int numInherits;
...@@ -101,7 +103,8 @@ getSchemaData(Archive *fout, int *numTablesPtr) ...@@ -101,7 +103,8 @@ getSchemaData(Archive *fout, int *numTablesPtr)
if (g_verbose) if (g_verbose)
write_msg(NULL, "reading schemas\n"); 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 * getTables should be done as soon as possible, so as to minimize the
...@@ -732,6 +735,17 @@ findCollationByOid(Oid oid) ...@@ -732,6 +735,17 @@ findCollationByOid(Oid oid)
return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations); 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 * findParentsByOid
......
...@@ -129,10 +129,6 @@ char g_comment_end[10]; ...@@ -129,10 +129,6 @@ char g_comment_end[10];
static const CatalogId nilCatalogId = {0, 0}; 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 */ /* flags for various command-line long options */
static int binary_upgrade = 0; static int binary_upgrade = 0;
static int disable_dollar_quoting = 0; static int disable_dollar_quoting = 0;
...@@ -2595,8 +2591,7 @@ getNamespaces(Archive *fout, int *numNamespaces) ...@@ -2595,8 +2591,7 @@ getNamespaces(Archive *fout, int *numNamespaces)
selectDumpableNamespace(&nsinfo[1]); selectDumpableNamespace(&nsinfo[1]);
g_namespaces = nsinfo; *numNamespaces = 2;
g_numNamespaces = *numNamespaces = 2;
return nsinfo; return nsinfo;
} }
...@@ -2648,8 +2643,7 @@ getNamespaces(Archive *fout, int *numNamespaces) ...@@ -2648,8 +2643,7 @@ getNamespaces(Archive *fout, int *numNamespaces)
PQclear(res); PQclear(res);
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
g_namespaces = nsinfo; *numNamespaces = ntups;
g_numNamespaces = *numNamespaces = ntups;
return nsinfo; return nsinfo;
} }
...@@ -2660,35 +2654,34 @@ getNamespaces(Archive *fout, int *numNamespaces) ...@@ -2660,35 +2654,34 @@ getNamespaces(Archive *fout, int *numNamespaces)
* getNamespaces * getNamespaces
* *
* NB: for pre-7.3 source database, we use object OID to guess whether it's * 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 * static NamespaceInfo *
findNamespace(Archive *fout, Oid nsoid, Oid objoid) findNamespace(Archive *fout, Oid nsoid, Oid objoid)
{ {
int i; NamespaceInfo *nsinfo;
if (fout->remoteVersion >= 70300) if (fout->remoteVersion >= 70300)
{ {
for (i = 0; i < g_numNamespaces; i++) nsinfo = findNamespaceByOid(nsoid);
{
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);
} }
else 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) if (objoid > g_last_builtin_oid)
i = 0; /* user object */ i = 0; /* user object */
else else
i = 1; /* system object */ 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); ...@@ -511,6 +511,7 @@ extern TypeInfo *findTypeByOid(Oid oid);
extern FuncInfo *findFuncByOid(Oid oid); extern FuncInfo *findFuncByOid(Oid oid);
extern OprInfo *findOprByOid(Oid oid); extern OprInfo *findOprByOid(Oid oid);
extern CollInfo *findCollationByOid(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_oid_list_append(SimpleOidList *list, Oid val);
extern void simple_string_list_append(SimpleStringList *list, const char *val); extern void simple_string_list_append(SimpleStringList *list, const char *val);
......
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