aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-05-25 14:35:37 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-05-25 14:35:37 -0400
commit73cc7d3b240e1d46b1996382e5735a820f8bc3f7 (patch)
treee9e075cc01cda2ea9403f8b477ceac512991fb30 /src
parent45ca31d6a7eaf91dc65fd5cf2b140320feb3fa3f (diff)
downloadpostgresql-73cc7d3b240e1d46b1996382e5735a820f8bc3f7.tar.gz
postgresql-73cc7d3b240e1d46b1996382e5735a820f8bc3f7.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/common.c18
-rw-r--r--src/bin/pg_dump/pg_dump.c35
-rw-r--r--src/bin/pg_dump/pg_dump.h1
3 files changed, 31 insertions, 23 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 9ec180decad..42d3645a6d4 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -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
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 6e13b746289..46ab6ee2bbc 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -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;
}
/*
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 5d6125c4259..f26d8d3ab66 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -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);