7878 * Portions Copyright (c) 1994, Regents of the University of California
7979 *
8080 * IDENTIFICATION
81- * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.50 2005/09/23 15:36:57 tgl Exp $
81+ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.51 2005/10/03 22:55:54 tgl Exp $
8282 *
8383 *-------------------------------------------------------------------------
8484 */
9595#include "utils/logtape.h"
9696#include "utils/lsyscache.h"
9797#include "utils/memutils.h"
98+ #include "utils/pg_rusage.h"
9899#include "utils/syscache.h"
99100#include "utils/tuplesort.h"
100101
101102
103+ /* GUC variable */
104+ #ifdef TRACE_SORT
105+ bool trace_sort = false;
106+ #endif
107+
108+
102109/*
103110 * Possible states of a Tuplesort object. These denote the states that
104111 * persist between calls of Tuplesort routines.
@@ -283,6 +290,13 @@ struct Tuplesortstate
283290/* we need typelen and byval in order to know how to copy the Datums. */
284291int datumTypeLen ;
285292bool datumTypeByVal ;
293+
294+ /*
295+ * Resource snapshot for time of sort start.
296+ */
297+ #ifdef TRACE_SORT
298+ PGRUsage ru_start ;
299+ #endif
286300};
287301
288302#define COMPARETUP (state ,a ,b )((*(state)->comparetup) (state, a, b))
@@ -422,6 +436,11 @@ tuplesort_begin_common(int workMem, bool randomAccess)
422436
423437state = (Tuplesortstate * )palloc0 (sizeof (Tuplesortstate ));
424438
439+ #ifdef TRACE_SORT
440+ if (trace_sort )
441+ pg_rusage_init (& state -> ru_start );
442+ #endif
443+
425444state -> status = TSS_INITIAL ;
426445state -> randomAccess = randomAccess ;
427446state -> availMem = workMem * 1024L ;
@@ -456,6 +475,13 @@ tuplesort_begin_heap(TupleDesc tupDesc,
456475
457476AssertArg (nkeys > 0 );
458477
478+ #ifdef TRACE_SORT
479+ if (trace_sort )
480+ elog (NOTICE ,
481+ "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c" ,
482+ nkeys ,workMem ,randomAccess ?'t' :'f' );
483+ #endif
484+
459485state -> comparetup = comparetup_heap ;
460486state -> copytup = copytup_heap ;
461487state -> writetup = writetup_heap ;
@@ -499,6 +525,14 @@ tuplesort_begin_index(Relation indexRel,
499525{
500526Tuplesortstate * state = tuplesort_begin_common (workMem ,randomAccess );
501527
528+ #ifdef TRACE_SORT
529+ if (trace_sort )
530+ elog (NOTICE ,
531+ "begin index sort: unique = %c, workMem = %d, randomAccess = %c" ,
532+ enforceUnique ?'t' :'f' ,
533+ workMem ,randomAccess ?'t' :'f' );
534+ #endif
535+
502536state -> comparetup = comparetup_index ;
503537state -> copytup = copytup_index ;
504538state -> writetup = writetup_index ;
@@ -522,6 +556,13 @@ tuplesort_begin_datum(Oid datumType,
522556int16 typlen ;
523557bool typbyval ;
524558
559+ #ifdef TRACE_SORT
560+ if (trace_sort )
561+ elog (NOTICE ,
562+ "begin datum sort: workMem = %d, randomAccess = %c" ,
563+ workMem ,randomAccess ?'t' :'f' );
564+ #endif
565+
525566state -> comparetup = comparetup_datum ;
526567state -> copytup = copytup_datum ;
527568state -> writetup = writetup_datum ;
@@ -573,6 +614,12 @@ tuplesort_end(Tuplesortstate *state)
573614if (state -> sortFnKinds )
574615pfree (state -> sortFnKinds );
575616
617+ #ifdef TRACE_SORT
618+ if (trace_sort )
619+ elog (NOTICE ,"sort ended: %s" ,
620+ pg_rusage_show (& state -> ru_start ));
621+ #endif
622+
576623pfree (state );
577624}
578625
@@ -712,6 +759,12 @@ puttuple_common(Tuplesortstate *state, void *tuple)
712759void
713760tuplesort_performsort (Tuplesortstate * state )
714761{
762+ #ifdef TRACE_SORT
763+ if (trace_sort )
764+ elog (NOTICE ,"performsort starting: %s" ,
765+ pg_rusage_show (& state -> ru_start ));
766+ #endif
767+
715768switch (state -> status )
716769{
717770case TSS_INITIAL :
@@ -751,6 +804,13 @@ tuplesort_performsort(Tuplesortstate *state)
751804elog (ERROR ,"invalid tuplesort state" );
752805break ;
753806}
807+
808+ #ifdef TRACE_SORT
809+ if (trace_sort )
810+ elog (NOTICE ,"performsort done%s: %s" ,
811+ (state -> status == TSS_FINALMERGE ) ?" (except final merge)" :"" ,
812+ pg_rusage_show (& state -> ru_start ));
813+ #endif
754814}
755815
756816/*
@@ -986,6 +1046,12 @@ inittapes(Tuplesortstate *state)
9861046int ntuples ,
9871047j ;
9881048
1049+ #ifdef TRACE_SORT
1050+ if (trace_sort )
1051+ elog (NOTICE ,"switching to external sort: %s" ,
1052+ pg_rusage_show (& state -> ru_start ));
1053+ #endif
1054+
9891055state -> tapeset = LogicalTapeSetCreate (MAXTAPES );
9901056
9911057/*
@@ -1243,6 +1309,12 @@ mergeonerun(Tuplesortstate *state)
12431309 */
12441310markrunend (state ,destTape );
12451311state -> tp_runs [TAPERANGE ]++ ;
1312+
1313+ #ifdef TRACE_SORT
1314+ if (trace_sort )
1315+ elog (NOTICE ,"finished merge step: %s" ,
1316+ pg_rusage_show (& state -> ru_start ));
1317+ #endif
12461318}
12471319
12481320/*
@@ -1456,6 +1528,14 @@ dumptuples(Tuplesortstate *state, bool alltuples)
14561528state -> tp_runs [state -> destTape ]++ ;
14571529state -> tp_dummy [state -> destTape ]-- ;/* per Alg D step D2 */
14581530
1531+ #ifdef TRACE_SORT
1532+ if (trace_sort )
1533+ elog (NOTICE ,"finished writing%s run %d: %s" ,
1534+ (state -> memtupcount == 0 ) ?" final" :"" ,
1535+ state -> currentRun ,
1536+ pg_rusage_show (& state -> ru_start ));
1537+ #endif
1538+
14591539/*
14601540 * Done if heap is empty, else prepare for new run.
14611541 */