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
3ce6fa5568
commit
5e0f3c793a
@ -50,14 +50,17 @@ 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 numNamespaces;
|
||||
static DumpableObject **tblinfoindex;
|
||||
static DumpableObject **typinfoindex;
|
||||
static DumpableObject **funinfoindex;
|
||||
static DumpableObject **oprinfoindex;
|
||||
static DumpableObject **nspinfoindex;
|
||||
|
||||
|
||||
static void flagInhTables(TableInfo *tbinfo, int numTables,
|
||||
@ -78,7 +81,6 @@ static int strInArray(const char *pattern, char **arr, int arr_size);
|
||||
TableInfo *
|
||||
getSchemaData(int *numTablesPtr)
|
||||
{
|
||||
NamespaceInfo *nsinfo;
|
||||
AggInfo *agginfo;
|
||||
InhInfo *inhinfo;
|
||||
RuleInfo *ruleinfo;
|
||||
@ -93,7 +95,6 @@ getSchemaData(int *numTablesPtr)
|
||||
TSConfigInfo *cfginfo;
|
||||
FdwInfo *fdwinfo;
|
||||
ForeignServerInfo *srvinfo;
|
||||
int numNamespaces;
|
||||
int numAggregates;
|
||||
int numInherits;
|
||||
int numRules;
|
||||
@ -111,7 +112,8 @@ getSchemaData(int *numTablesPtr)
|
||||
|
||||
if (g_verbose)
|
||||
write_msg(NULL, "reading schemas\n");
|
||||
nsinfo = getNamespaces(&numNamespaces);
|
||||
nspinfo = getNamespaces(&numNamespaces);
|
||||
nspinfoindex = buildIndexArray(nspinfo, numNamespaces, sizeof(NamespaceInfo));
|
||||
|
||||
/*
|
||||
* getTables should be done as soon as possible, so as to minimize the
|
||||
@ -708,6 +710,17 @@ findOprByOid(Oid oid)
|
||||
return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -102,10 +102,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;
|
||||
@ -2184,8 +2180,7 @@ getNamespaces(int *numNamespaces)
|
||||
|
||||
selectDumpableNamespace(&nsinfo[1]);
|
||||
|
||||
g_namespaces = nsinfo;
|
||||
g_numNamespaces = *numNamespaces = 2;
|
||||
*numNamespaces = 2;
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
@ -2238,8 +2233,7 @@ getNamespaces(int *numNamespaces)
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
|
||||
g_namespaces = nsinfo;
|
||||
g_numNamespaces = *numNamespaces = ntups;
|
||||
*numNamespaces = ntups;
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
@ -2250,36 +2244,37 @@ getNamespaces(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(Oid nsoid, Oid objoid)
|
||||
{
|
||||
int i;
|
||||
NamespaceInfo *nsinfo;
|
||||
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
for (i = 0; i < g_numNamespaces; i++)
|
||||
{
|
||||
NamespaceInfo *nsinfo = &g_namespaces[i];
|
||||
|
||||
if (nsoid == nsinfo->dobj.catId.oid)
|
||||
return nsinfo;
|
||||
}
|
||||
write_msg(NULL, "schema with OID %u does not exist\n", nsoid);
|
||||
exit_nicely();
|
||||
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)
|
||||
{
|
||||
write_msg(NULL, "schema with OID %u does not exist\n", nsoid);
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
return nsinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -457,6 +457,7 @@ extern TableInfo *findTableByOid(Oid oid);
|
||||
extern TypeInfo *findTypeByOid(Oid oid);
|
||||
extern FuncInfo *findFuncByOid(Oid oid);
|
||||
extern OprInfo *findOprByOid(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…
x
Reference in New Issue
Block a user