Skip to content

Commit 7bb11a9

Browse files
committed
Speed up findObjectByCatalogId() to get rid of the other salient
bottleneck in the new pg_dump code.
1 parent f8495a6 commit 7bb11a9

File tree

1 file changed

+71
-11
lines changed

1 file changed

+71
-11
lines changed

src/bin/pg_dump/common.c

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.78 2003/12/06 03:00:11 tgl Exp $
14+
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.79 2003/12/07 03:14:01 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -37,6 +37,13 @@ static DumpableObject **dumpIdMap = NULL;
3737
static int allocedDumpIds = 0;
3838
static DumpId lastDumpId = 0;
3939

40+
/*
41+
* Variables for mapping CatalogId to DumpableObject
42+
*/
43+
static bool catalogIdMapValid = false;
44+
static DumpableObject **catalogIdMap = NULL;
45+
static int numCatalogIds = 0;
46+
4047
/*
4148
* These variables are static to avoid the notational cruft of having to pass
4249
* them into findTableByOid() and friends.
@@ -51,12 +58,13 @@ static int numFuncs;
5158
static int numOperators;
5259

5360

54-
static void findParentsByOid(TableInfo *self,
55-
InhInfo *inhinfo, int numInherits);
5661
static void flagInhTables(TableInfo *tbinfo, int numTables,
5762
InhInfo *inhinfo, int numInherits);
5863
static void flagInhAttrs(TableInfo *tbinfo, int numTables,
5964
InhInfo *inhinfo, int numInherits);
65+
static int DOCatalogIdCompare(const void *p1, const void *p2);
66+
static void findParentsByOid(TableInfo *self,
67+
InhInfo *inhinfo, int numInherits);
6068
static int strInArray(const char *pattern, char **arr, int arr_size);
6169

6270

@@ -413,6 +421,9 @@ AssignDumpId(DumpableObject *dobj)
413421
allocedDumpIds = newAlloc;
414422
}
415423
dumpIdMap[dobj->dumpId] = dobj;
424+
425+
/* mark catalogIdMap invalid, but don't rebuild it yet */
426+
catalogIdMapValid = false;
416427
}
417428

418429
/*
@@ -454,25 +465,74 @@ findObjectByDumpId(DumpId dumpId)
454465
*
455466
* Returns NULL for unknown ID
456467
*
457-
* NOTE: should hash this, but just do linear search for now
468+
* We use binary search in a sorted list that is built on first call.
469+
* If AssignDumpId() and findObjectByCatalogId() calls were intermixed,
470+
* the code would work, but possibly be very slow. In the current usage
471+
* pattern that does not happen, indeed we only need to build the list once.
458472
*/
459473
DumpableObject *
460474
findObjectByCatalogId(CatalogId catalogId)
461475
{
462-
DumpId i;
476+
DumpableObject **low;
477+
DumpableObject **high;
463478

464-
for (i = 1; i < allocedDumpIds; i++)
479+
if (!catalogIdMapValid)
465480
{
466-
DumpableObject *dobj = dumpIdMap[i];
481+
if (catalogIdMap)
482+
free(catalogIdMap);
483+
getDumpableObjects(&catalogIdMap, &numCatalogIds);
484+
if (numCatalogIds > 1)
485+
qsort((void *) catalogIdMap, numCatalogIds,
486+
sizeof(DumpableObject *), DOCatalogIdCompare);
487+
catalogIdMapValid = true;
488+
}
467489

468-
if (dobj &&
469-
dobj->catId.tableoid == catalogId.tableoid &&
470-
dobj->catId.oid == catalogId.oid)
471-
return dobj;
490+
/*
491+
* We could use bsearch() here, but the notational cruft of calling
492+
* bsearch is nearly as bad as doing it ourselves; and the generalized
493+
* bsearch function is noticeably slower as well.
494+
*/
495+
if (numCatalogIds <= 0)
496+
return NULL;
497+
low = catalogIdMap;
498+
high = catalogIdMap + (numCatalogIds - 1);
499+
while (low <= high)
500+
{
501+
DumpableObject **middle;
502+
int difference;
503+
504+
middle = low + (high - low) / 2;
505+
/* comparison must match DOCatalogIdCompare, below */
506+
difference = oidcmp((*middle)->catId.oid, catalogId.oid);
507+
if (difference == 0)
508+
difference = oidcmp((*middle)->catId.tableoid, catalogId.tableoid);
509+
if (difference == 0)
510+
return *middle;
511+
else if (difference < 0)
512+
low = middle + 1;
513+
else
514+
high = middle - 1;
472515
}
473516
return NULL;
474517
}
475518

519+
static int
520+
DOCatalogIdCompare(const void *p1, const void *p2)
521+
{
522+
DumpableObject *obj1 = *(DumpableObject **) p1;
523+
DumpableObject *obj2 = *(DumpableObject **) p2;
524+
int cmpval;
525+
526+
/*
527+
* Compare OID first since it's usually unique, whereas there will
528+
* only be a few distinct values of tableoid.
529+
*/
530+
cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid);
531+
if (cmpval == 0)
532+
cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid);
533+
return cmpval;
534+
}
535+
476536
/*
477537
* Build an array of pointers to all known dumpable objects
478538
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy