diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-25 14:35:41 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-25 14:35:41 -0400 |
commit | 1a93588ffcad3e4876c9610c0a35d79c7fcdeffe (patch) | |
tree | 839e744d925a458f14331eea9d145369267e2fce /src | |
parent | 4615d2ca28fe9dff6e5ebaebd6caf190a0c78ba5 (diff) | |
download | postgresql-1a93588ffcad3e4876c9610c0a35d79c7fcdeffe.tar.gz postgresql-1a93588ffcad3e4876c9610c0a35d79c7fcdeffe.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.c | 18 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 39 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.h | 1 |
3 files changed, 34 insertions, 24 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index d52566d64e4..7415f0d00fb 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -50,16 +50,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, @@ -83,7 +86,6 @@ getSchemaData(int *numTablesPtr) ExtensionInfo *extinfo; InhInfo *inhinfo; CollInfo *collinfo; - int numNamespaces; int numExtensions; int numAggregates; int numInherits; @@ -103,7 +105,8 @@ getSchemaData(int *numTablesPtr) if (g_verbose) write_msg(NULL, "reading schemas\n"); - getNamespaces(&numNamespaces); + nspinfo = getNamespaces(&numNamespaces); + nspinfoindex = buildIndexArray(nspinfo, numNamespaces, sizeof(NamespaceInfo)); /* * getTables should be done as soon as possible, so as to minimize the @@ -734,6 +737,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 a4c6d420ec6..665f758db04 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -126,10 +126,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; @@ -2619,8 +2615,7 @@ getNamespaces(int *numNamespaces) selectDumpableNamespace(&nsinfo[1]); - g_namespaces = nsinfo; - g_numNamespaces = *numNamespaces = 2; + *numNamespaces = 2; return nsinfo; } @@ -2673,8 +2668,7 @@ getNamespaces(int *numNamespaces) PQclear(res); destroyPQExpBuffer(query); - g_namespaces = nsinfo; - g_numNamespaces = *numNamespaces = ntups; + *numNamespaces = ntups; return nsinfo; } @@ -2685,36 +2679,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; } /* diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 37b19d2f12e..21d42f8ea53 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -506,6 +506,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); |