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;
3737static int allocedDumpIds = 0 ;
3838static 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 intnumFuncs;
5158static int numOperators ;
5259
5360
54- static void findParentsByOid (TableInfo * self ,
55- InhInfo * inhinfo ,int numInherits );
5661static void flagInhTables (TableInfo * tbinfo ,int numTables ,
5762InhInfo * inhinfo ,int numInherits );
5863static void flagInhAttrs (TableInfo * tbinfo ,int numTables ,
5964InhInfo * inhinfo ,int numInherits );
65+ static int DOCatalogIdCompare (const void * p1 ,const void * p2 );
66+ static void findParentsByOid (TableInfo * self ,
67+ InhInfo * inhinfo ,int numInherits );
6068static int strInArray (const char * pattern ,char * * arr ,int arr_size );
6169
6270
@@ -413,6 +421,9 @@ AssignDumpId(DumpableObject *dobj)
413421allocedDumpIds = newAlloc ;
414422}
415423dumpIdMap [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 */
459473DumpableObject *
460474findObjectByCatalogId (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}
473516return 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 *