1313 *
1414 *Copyright (c) 2001-2007, PostgreSQL Global Development Group
1515 *
16- *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.142 2007/01/05 22:19:36 momjian Exp $
16+ *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.143 2007/01/11 23:06:03 tgl Exp $
1717 * ----------
1818 */
1919#include "postgres.h"
@@ -159,6 +159,7 @@ static void pgstat_write_statsfile(void);
159159static void pgstat_read_statsfile (HTAB * * dbhash ,Oid onlydb );
160160static void backend_read_statsfile (void );
161161static void pgstat_read_current_status (void );
162+ static HTAB * pgstat_collect_oids (Oid catalogid );
162163
163164static void pgstat_setheader (PgStat_MsgHdr * hdr ,StatMsgType mtype );
164165static void pgstat_send (void * msg ,int len );
@@ -657,10 +658,7 @@ pgstat_report_tabstat(void)
657658void
658659pgstat_vacuum_tabstat (void )
659660{
660- List * oidlist ;
661- Relation rel ;
662- HeapScanDesc scan ;
663- HeapTuple tup ;
661+ HTAB * htab ;
664662PgStat_MsgTabpurge msg ;
665663HASH_SEQ_STATUS hstat ;
666664PgStat_StatDBEntry * dbentry ;
@@ -679,15 +677,7 @@ pgstat_vacuum_tabstat(void)
679677/*
680678 * Read pg_database and make a list of OIDs of all existing databases
681679 */
682- oidlist = NIL ;
683- rel = heap_open (DatabaseRelationId ,AccessShareLock );
684- scan = heap_beginscan (rel ,SnapshotNow ,0 ,NULL );
685- while ((tup = heap_getnext (scan ,ForwardScanDirection ))!= NULL )
686- {
687- oidlist = lappend_oid (oidlist ,HeapTupleGetOid (tup ));
688- }
689- heap_endscan (scan );
690- heap_close (rel ,AccessShareLock );
680+ htab = pgstat_collect_oids (DatabaseRelationId );
691681
692682/*
693683 * Search the database hash table for dead databases and tell the
@@ -698,12 +688,14 @@ pgstat_vacuum_tabstat(void)
698688{
699689Oid dbid = dbentry -> databaseid ;
700690
701- if (!list_member_oid (oidlist ,dbid ))
691+ CHECK_FOR_INTERRUPTS ();
692+
693+ if (hash_search (htab , (void * )& dbid ,HASH_FIND ,NULL )== NULL )
702694pgstat_drop_database (dbid );
703695}
704696
705697/* Clean up */
706- list_free ( oidlist );
698+ hash_destroy ( htab );
707699
708700/*
709701 * Lookup our own database entry; if not found, nothing more to do.
@@ -717,15 +709,7 @@ pgstat_vacuum_tabstat(void)
717709/*
718710 * Similarly to above, make a list of all known relations in this DB.
719711 */
720- oidlist = NIL ;
721- rel = heap_open (RelationRelationId ,AccessShareLock );
722- scan = heap_beginscan (rel ,SnapshotNow ,0 ,NULL );
723- while ((tup = heap_getnext (scan ,ForwardScanDirection ))!= NULL )
724- {
725- oidlist = lappend_oid (oidlist ,HeapTupleGetOid (tup ));
726- }
727- heap_endscan (scan );
728- heap_close (rel ,AccessShareLock );
712+ htab = pgstat_collect_oids (RelationRelationId );
729713
730714/*
731715 * Initialize our messages table counter to zero
@@ -738,13 +722,17 @@ pgstat_vacuum_tabstat(void)
738722hash_seq_init (& hstat ,dbentry -> tables );
739723while ((tabentry = (PgStat_StatTabEntry * )hash_seq_search (& hstat ))!= NULL )
740724{
741- if (list_member_oid (oidlist ,tabentry -> tableid ))
725+ Oid tabid = tabentry -> tableid ;
726+
727+ CHECK_FOR_INTERRUPTS ();
728+
729+ if (hash_search (htab , (void * )& tabid ,HASH_FIND ,NULL )!= NULL )
742730continue ;
743731
744732/*
745733 * Not there, so add this table's Oid to the message
746734 */
747- msg .m_tableid [msg .m_nentries ++ ]= tabentry -> tableid ;
735+ msg .m_tableid [msg .m_nentries ++ ]= tabid ;
748736
749737/*
750738 * If the message is full, send it out and reinitialize to empty
@@ -776,7 +764,50 @@ pgstat_vacuum_tabstat(void)
776764}
777765
778766/* Clean up */
779- list_free (oidlist );
767+ hash_destroy (htab );
768+ }
769+
770+
771+ /* ----------
772+ * pgstat_collect_oids() -
773+ *
774+ *Collect the OIDs of either all databases or all tables, according to
775+ *the parameter, into a temporary hash table. Caller should hash_destroy
776+ *the result when done with it.
777+ * ----------
778+ */
779+ static HTAB *
780+ pgstat_collect_oids (Oid catalogid )
781+ {
782+ HTAB * htab ;
783+ HASHCTL hash_ctl ;
784+ Relation rel ;
785+ HeapScanDesc scan ;
786+ HeapTuple tup ;
787+
788+ memset (& hash_ctl ,0 ,sizeof (hash_ctl ));
789+ hash_ctl .keysize = sizeof (Oid );
790+ hash_ctl .entrysize = sizeof (Oid );
791+ hash_ctl .hash = oid_hash ;
792+ htab = hash_create ("Temporary table of OIDs" ,
793+ PGSTAT_TAB_HASH_SIZE ,
794+ & hash_ctl ,
795+ HASH_ELEM |HASH_FUNCTION );
796+
797+ rel = heap_open (catalogid ,AccessShareLock );
798+ scan = heap_beginscan (rel ,SnapshotNow ,0 ,NULL );
799+ while ((tup = heap_getnext (scan ,ForwardScanDirection ))!= NULL )
800+ {
801+ Oid thisoid = HeapTupleGetOid (tup );
802+
803+ CHECK_FOR_INTERRUPTS ();
804+
805+ (void )hash_search (htab , (void * )& thisoid ,HASH_ENTER ,NULL );
806+ }
807+ heap_endscan (scan );
808+ heap_close (rel ,AccessShareLock );
809+
810+ return htab ;
780811}
781812
782813