mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03: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:
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user