1111 *
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.97 2007/08/21 01:11:20 tgl Exp $
14+ * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.98 2007/09/23 23:39:36 tgl Exp $
1515 *
1616 *-------------------------------------------------------------------------
1717 */
@@ -41,7 +41,11 @@ static intnumCatalogIds = 0;
4141
4242/*
4343 * These variables are static to avoid the notational cruft of having to pass
44- * them into findTableByOid() and friends.
44+ * them into findTableByOid() and friends. For each of these arrays, we
45+ * build a sorted-by-OID index array immediately after it's built, and then
46+ * we use binary search in findTableByOid() and friends. (qsort'ing the base
47+ * arrays themselves would be simpler, but it doesn't work because pg_dump.c
48+ * may have already established pointers between items.)
4549 */
4650static TableInfo * tblinfo ;
4751static TypeInfo * typinfo ;
@@ -51,12 +55,18 @@ static intnumTables;
5155static int numTypes ;
5256static int numFuncs ;
5357static int numOperators ;
58+ static DumpableObject * * tblinfoindex ;
59+ static DumpableObject * * typinfoindex ;
60+ static DumpableObject * * funinfoindex ;
61+ static DumpableObject * * oprinfoindex ;
5462
5563
5664static void flagInhTables (TableInfo * tbinfo ,int numTables ,
5765InhInfo * inhinfo ,int numInherits );
5866static void flagInhAttrs (TableInfo * tbinfo ,int numTables ,
5967InhInfo * inhinfo ,int numInherits );
68+ static DumpableObject * * buildIndexArray (void * objArray ,int numObjs ,
69+ Size objSize );
6070static int DOCatalogIdCompare (const void * p1 ,const void * p2 );
6171static void findParentsByOid (TableInfo * self ,
6272InhInfo * inhinfo ,int numInherits );
@@ -104,11 +114,13 @@ getSchemaData(int *numTablesPtr)
104114if (g_verbose )
105115write_msg (NULL ,"reading user-defined functions\n" );
106116funinfo = getFuncs (& numFuncs );
117+ funinfoindex = buildIndexArray (funinfo ,numFuncs ,sizeof (FuncInfo ));
107118
108119/* this must be after getFuncs */
109120if (g_verbose )
110121write_msg (NULL ,"reading user-defined types\n" );
111122typinfo = getTypes (& numTypes );
123+ typinfoindex = buildIndexArray (typinfo ,numTypes ,sizeof (TypeInfo ));
112124
113125/* this must be after getFuncs, too */
114126if (g_verbose )
@@ -122,6 +134,7 @@ getSchemaData(int *numTablesPtr)
122134if (g_verbose )
123135write_msg (NULL ,"reading user-defined operators\n" );
124136oprinfo = getOperators (& numOperators );
137+ oprinfoindex = buildIndexArray (oprinfo ,numOperators ,sizeof (OprInfo ));
125138
126139if (g_verbose )
127140write_msg (NULL ,"reading user-defined operator classes\n" );
@@ -154,6 +167,7 @@ getSchemaData(int *numTablesPtr)
154167if (g_verbose )
155168write_msg (NULL ,"reading user-defined tables\n" );
156169tblinfo = getTables (& numTables );
170+ tblinfoindex = buildIndexArray (tblinfo ,numTables ,sizeof (TableInfo ));
157171
158172if (g_verbose )
159173write_msg (NULL ,"reading table inheritance information\n" );
@@ -540,6 +554,70 @@ findObjectByCatalogId(CatalogId catalogId)
540554return NULL ;
541555}
542556
557+ /*
558+ * Find a DumpableObject by OID, in a pre-sorted array of one type of object
559+ *
560+ * Returns NULL for unknown OID
561+ */
562+ static DumpableObject *
563+ findObjectByOid (Oid oid ,DumpableObject * * indexArray ,int numObjs )
564+ {
565+ DumpableObject * * low ;
566+ DumpableObject * * high ;
567+
568+ /*
569+ * This is the same as findObjectByCatalogId except we assume we need
570+ * not look at table OID because the objects are all the same type.
571+ *
572+ * We could use bsearch() here, but the notational cruft of calling
573+ * bsearch is nearly as bad as doing it ourselves; and the generalized
574+ * bsearch function is noticeably slower as well.
575+ */
576+ if (numObjs <=0 )
577+ return NULL ;
578+ low = indexArray ;
579+ high = indexArray + (numObjs - 1 );
580+ while (low <=high )
581+ {
582+ DumpableObject * * middle ;
583+ int difference ;
584+
585+ middle = low + (high - low ) /2 ;
586+ difference = oidcmp ((* middle )-> catId .oid ,oid );
587+ if (difference == 0 )
588+ return * middle ;
589+ else if (difference < 0 )
590+ low = middle + 1 ;
591+ else
592+ high = middle - 1 ;
593+ }
594+ return NULL ;
595+ }
596+
597+ /*
598+ * Build an index array of DumpableObject pointers, sorted by OID
599+ */
600+ static DumpableObject * *
601+ buildIndexArray (void * objArray ,int numObjs ,Size objSize )
602+ {
603+ DumpableObject * * ptrs ;
604+ int i ;
605+
606+ ptrs = (DumpableObject * * )malloc (numObjs * sizeof (DumpableObject * ));
607+ for (i = 0 ;i < numObjs ;i ++ )
608+ ptrs [i ]= (DumpableObject * ) ((char * )objArray + i * objSize );
609+
610+ /* We can use DOCatalogIdCompare to sort since its first key is OID */
611+ if (numObjs > 1 )
612+ qsort ((void * )ptrs ,numObjs ,sizeof (DumpableObject * ),
613+ DOCatalogIdCompare );
614+
615+ return ptrs ;
616+ }
617+
618+ /*
619+ * qsort comparator for pointers to DumpableObjects
620+ */
543621static int
544622DOCatalogIdCompare (const void * p1 ,const void * p2 )
545623{
@@ -630,80 +708,44 @@ removeObjectDependency(DumpableObject *dobj, DumpId refId)
630708 * findTableByOid
631709 * finds the entry (in tblinfo) of the table with the given oid
632710 * returns NULL if not found
633- *
634- * NOTE: should hash this, but just do linear search for now
635711 */
636712TableInfo *
637713findTableByOid (Oid oid )
638714{
639- int i ;
640-
641- for (i = 0 ;i < numTables ;i ++ )
642- {
643- if (tblinfo [i ].dobj .catId .oid == oid )
644- return & tblinfo [i ];
645- }
646- return NULL ;
715+ return (TableInfo * )findObjectByOid (oid ,tblinfoindex ,numTables );
647716}
648717
649718/*
650719 * findTypeByOid
651720 * finds the entry (in typinfo) of the type with the given oid
652721 * returns NULL if not found
653- *
654- * NOTE: should hash this, but just do linear search for now
655722 */
656723TypeInfo *
657724findTypeByOid (Oid oid )
658725{
659- int i ;
660-
661- for (i = 0 ;i < numTypes ;i ++ )
662- {
663- if (typinfo [i ].dobj .catId .oid == oid )
664- return & typinfo [i ];
665- }
666- return NULL ;
726+ return (TypeInfo * )findObjectByOid (oid ,typinfoindex ,numTypes );
667727}
668728
669729/*
670730 * findFuncByOid
671731 * finds the entry (in funinfo) of the function with the given oid
672732 * returns NULL if not found
673- *
674- * NOTE: should hash this, but just do linear search for now
675733 */
676734FuncInfo *
677735findFuncByOid (Oid oid )
678736{
679- int i ;
680-
681- for (i = 0 ;i < numFuncs ;i ++ )
682- {
683- if (funinfo [i ].dobj .catId .oid == oid )
684- return & funinfo [i ];
685- }
686- return NULL ;
737+ return (FuncInfo * )findObjectByOid (oid ,funinfoindex ,numFuncs );
687738}
688739
689740/*
690741 * findOprByOid
691742 * finds the entry (in oprinfo) of the operator with the given oid
692743 * returns NULL if not found
693- *
694- * NOTE: should hash this, but just do linear search for now
695744 */
696745OprInfo *
697746findOprByOid (Oid oid )
698747{
699- int i ;
700-
701- for (i = 0 ;i < numOperators ;i ++ )
702- {
703- if (oprinfo [i ].dobj .catId .oid == oid )
704- return & oprinfo [i ];
705- }
706- return NULL ;
748+ return (OprInfo * )findObjectByOid (oid ,oprinfoindex ,numOperators );
707749}
708750
709751