|
91 | 91 | * Portions Copyright (c) 1994, Regents of the University of California
|
92 | 92 | *
|
93 | 93 | * IDENTIFICATION
|
94 |
| - * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.75 2007/05/0401:13:44 tgl Exp $ |
| 94 | + * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.76 2007/05/0421:29:53 tgl Exp $ |
95 | 95 | *
|
96 | 96 | *-------------------------------------------------------------------------
|
97 | 97 | */
|
@@ -196,6 +196,7 @@ struct Tuplesortstate
|
196 | 196 | boolrandomAccess;/* did caller request random access? */
|
197 | 197 | boolbounded;/* did caller specify a maximum number of
|
198 | 198 | * tuples to return? */
|
| 199 | +boolboundUsed;/* true if we made use of a bounded heap */ |
199 | 200 | intbound;/* if bounded, the maximum number of tuples */
|
200 | 201 | longavailMem;/* remaining memory available, in bytes */
|
201 | 202 | longallowedMem;/* total memory allowed, in bytes */
|
@@ -505,6 +506,8 @@ tuplesort_begin_common(int workMem, bool randomAccess)
|
505 | 506 |
|
506 | 507 | state->status=TSS_INITIAL;
|
507 | 508 | state->randomAccess=randomAccess;
|
| 509 | +state->bounded= false; |
| 510 | +state->boundUsed= false; |
508 | 511 | state->allowedMem=workMem*1024L;
|
509 | 512 | state->availMem=state->allowedMem;
|
510 | 513 | state->sortcontext=sortcontext;
|
@@ -2113,6 +2116,64 @@ tuplesort_restorepos(Tuplesortstate *state)
|
2113 | 2116 | MemoryContextSwitchTo(oldcontext);
|
2114 | 2117 | }
|
2115 | 2118 |
|
| 2119 | +/* |
| 2120 | + * tuplesort_explain - produce a line of information for EXPLAIN ANALYZE |
| 2121 | + * |
| 2122 | + * This can be called after tuplesort_performsort() finishes to obtain |
| 2123 | + * printable summary information about how the sort was performed. |
| 2124 | + * |
| 2125 | + * The result is a palloc'd string. |
| 2126 | + */ |
| 2127 | +char* |
| 2128 | +tuplesort_explain(Tuplesortstate*state) |
| 2129 | +{ |
| 2130 | +char*result= (char*)palloc(100); |
| 2131 | +longspaceUsed; |
| 2132 | + |
| 2133 | +/* |
| 2134 | + * Note: it might seem we should print both memory and disk usage for a |
| 2135 | + * disk-based sort. However, the current code doesn't track memory space |
| 2136 | + * accurately once we have begun to return tuples to the caller (since |
| 2137 | + * we don't account for pfree's the caller is expected to do), so we |
| 2138 | + * cannot rely on availMem in a disk sort. This does not seem worth the |
| 2139 | + * overhead to fix. Is it worth creating an API for the memory context |
| 2140 | + * code to tell us how much is actually used in sortcontext? |
| 2141 | + */ |
| 2142 | +if (state->tapeset) |
| 2143 | +spaceUsed=LogicalTapeSetBlocks(state->tapeset)* (BLCKSZ /1024); |
| 2144 | +else |
| 2145 | +spaceUsed= (state->allowedMem-state->availMem+1023) /1024; |
| 2146 | + |
| 2147 | +switch (state->status) |
| 2148 | +{ |
| 2149 | +caseTSS_SORTEDINMEM: |
| 2150 | +if (state->boundUsed) |
| 2151 | +snprintf(result,100, |
| 2152 | +"Sort Method: top-N heapsort Memory: %ldkB", |
| 2153 | +spaceUsed); |
| 2154 | +else |
| 2155 | +snprintf(result,100, |
| 2156 | +"Sort Method: quicksort Memory: %ldkB", |
| 2157 | +spaceUsed); |
| 2158 | +break; |
| 2159 | +caseTSS_SORTEDONTAPE: |
| 2160 | +snprintf(result,100, |
| 2161 | +"Sort Method: external sort Disk: %ldkB", |
| 2162 | +spaceUsed); |
| 2163 | +break; |
| 2164 | +caseTSS_FINALMERGE: |
| 2165 | +snprintf(result,100, |
| 2166 | +"Sort Method: external merge Disk: %ldkB", |
| 2167 | +spaceUsed); |
| 2168 | +break; |
| 2169 | +default: |
| 2170 | +snprintf(result,100,"sort still in progress"); |
| 2171 | +break; |
| 2172 | +} |
| 2173 | + |
| 2174 | +returnresult; |
| 2175 | +} |
| 2176 | + |
2116 | 2177 |
|
2117 | 2178 | /*
|
2118 | 2179 | * Heap manipulation routines, per Knuth's Algorithm 5.2.3H.
|
@@ -2216,6 +2277,7 @@ sort_bounded_heap(Tuplesortstate *state)
|
2216 | 2277 | REVERSEDIRECTION(state);
|
2217 | 2278 |
|
2218 | 2279 | state->status=TSS_SORTEDINMEM;
|
| 2280 | +state->boundUsed= true; |
2219 | 2281 | }
|
2220 | 2282 |
|
2221 | 2283 | /*
|
|