78
78
* Portions Copyright (c) 1994, Regents of the University of California
79
79
*
80
80
* 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 $
82
82
*
83
83
*-------------------------------------------------------------------------
84
84
*/
95
95
#include "utils/logtape.h"
96
96
#include "utils/lsyscache.h"
97
97
#include "utils/memutils.h"
98
+ #include "utils/pg_rusage.h"
98
99
#include "utils/syscache.h"
99
100
#include "utils/tuplesort.h"
100
101
101
102
103
+ /* GUC variable */
104
+ #ifdef TRACE_SORT
105
+ bool trace_sort = false;
106
+ #endif
107
+
108
+
102
109
/*
103
110
* Possible states of a Tuplesort object. These denote the states that
104
111
* persist between calls of Tuplesort routines.
@@ -283,6 +290,13 @@ struct Tuplesortstate
283
290
/* we need typelen and byval in order to know how to copy the Datums. */
284
291
int datumTypeLen ;
285
292
bool datumTypeByVal ;
293
+
294
+ /*
295
+ * Resource snapshot for time of sort start.
296
+ */
297
+ #ifdef TRACE_SORT
298
+ PGRUsage ru_start ;
299
+ #endif
286
300
};
287
301
288
302
#define COMPARETUP (state ,a ,b ) ((*(state)->comparetup) (state, a, b))
@@ -422,6 +436,11 @@ tuplesort_begin_common(int workMem, bool randomAccess)
422
436
423
437
state = (Tuplesortstate * ) palloc0 (sizeof (Tuplesortstate ));
424
438
439
+ #ifdef TRACE_SORT
440
+ if (trace_sort )
441
+ pg_rusage_init (& state -> ru_start );
442
+ #endif
443
+
425
444
state -> status = TSS_INITIAL ;
426
445
state -> randomAccess = randomAccess ;
427
446
state -> availMem = workMem * 1024L ;
@@ -456,6 +475,13 @@ tuplesort_begin_heap(TupleDesc tupDesc,
456
475
457
476
AssertArg (nkeys > 0 );
458
477
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
+
459
485
state -> comparetup = comparetup_heap ;
460
486
state -> copytup = copytup_heap ;
461
487
state -> writetup = writetup_heap ;
@@ -499,6 +525,14 @@ tuplesort_begin_index(Relation indexRel,
499
525
{
500
526
Tuplesortstate * state = tuplesort_begin_common (workMem , randomAccess );
501
527
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
+
502
536
state -> comparetup = comparetup_index ;
503
537
state -> copytup = copytup_index ;
504
538
state -> writetup = writetup_index ;
@@ -522,6 +556,13 @@ tuplesort_begin_datum(Oid datumType,
522
556
int16 typlen ;
523
557
bool typbyval ;
524
558
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
+
525
566
state -> comparetup = comparetup_datum ;
526
567
state -> copytup = copytup_datum ;
527
568
state -> writetup = writetup_datum ;
@@ -573,6 +614,12 @@ tuplesort_end(Tuplesortstate *state)
573
614
if (state -> sortFnKinds )
574
615
pfree (state -> sortFnKinds );
575
616
617
+ #ifdef TRACE_SORT
618
+ if (trace_sort )
619
+ elog (NOTICE , "sort ended: %s" ,
620
+ pg_rusage_show (& state -> ru_start ));
621
+ #endif
622
+
576
623
pfree (state );
577
624
}
578
625
@@ -712,6 +759,12 @@ puttuple_common(Tuplesortstate *state, void *tuple)
712
759
void
713
760
tuplesort_performsort (Tuplesortstate * state )
714
761
{
762
+ #ifdef TRACE_SORT
763
+ if (trace_sort )
764
+ elog (NOTICE , "performsort starting: %s" ,
765
+ pg_rusage_show (& state -> ru_start ));
766
+ #endif
767
+
715
768
switch (state -> status )
716
769
{
717
770
case TSS_INITIAL :
@@ -751,6 +804,13 @@ tuplesort_performsort(Tuplesortstate *state)
751
804
elog (ERROR , "invalid tuplesort state" );
752
805
break ;
753
806
}
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
754
814
}
755
815
756
816
/*
@@ -986,6 +1046,12 @@ inittapes(Tuplesortstate *state)
986
1046
int ntuples ,
987
1047
j ;
988
1048
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
+
989
1055
state -> tapeset = LogicalTapeSetCreate (MAXTAPES );
990
1056
991
1057
/*
@@ -1243,6 +1309,12 @@ mergeonerun(Tuplesortstate *state)
1243
1309
*/
1244
1310
markrunend (state , destTape );
1245
1311
state -> 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
1246
1318
}
1247
1319
1248
1320
/*
@@ -1456,6 +1528,14 @@ dumptuples(Tuplesortstate *state, bool alltuples)
1456
1528
state -> tp_runs [state -> destTape ]++ ;
1457
1529
state -> tp_dummy [state -> destTape ]-- ; /* per Alg D step D2 */
1458
1530
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
+
1459
1539
/*
1460
1540
* Done if heap is empty, else prepare for new run.
1461
1541
*/
0 commit comments