@@ -288,11 +288,7 @@ struct Tuplesortstate
288
288
289
289
/*
290
290
* Function to write a stored tuple onto tape. The representation of the
291
- * tuple on tape need not be the same as it is in memory; requirements on
292
- * the tape representation are given below. Unless the slab allocator is
293
- * used, after writing the tuple, pfree() the out-of-line data (not the
294
- * SortTuple struct!), and increase state->availMem by the amount of
295
- * memory space thereby released.
291
+ * tuple on tape need not be the same as it is in memory.
296
292
*/
297
293
void (* writetup ) (Tuplesortstate * state , LogicalTape * tape ,
298
294
SortTuple * stup );
@@ -549,7 +545,7 @@ struct Sharedsort
549
545
550
546
#define REMOVEABBREV (state ,stup ,count ) ((*(state)->removeabbrev) (state, stup, count))
551
547
#define COMPARETUP (state ,a ,b ) ((*(state)->comparetup) (a, b, state))
552
- #define WRITETUP (state ,tape ,stup ) ((*(state)->writetup) (state, tape, stup))
548
+ #define WRITETUP (state ,tape ,stup ) (writetuple (state, tape, stup))
553
549
#define READTUP (state ,stup ,tape ,len ) ((*(state)->readtup) (state, stup, tape, len))
554
550
#define LACKMEM (state ) ((state)->availMem < 0 && !(state)->slabAllocatorUsed)
555
551
#define USEMEM (state ,amt ) ((state)->availMem -= (amt))
@@ -618,6 +614,8 @@ static Tuplesortstate *tuplesort_begin_common(int workMem,
618
614
static void tuplesort_begin_batch (Tuplesortstate * state );
619
615
static void puttuple_common (Tuplesortstate * state , SortTuple * tuple ,
620
616
bool useAbbrev );
617
+ static void writetuple (Tuplesortstate * state , LogicalTape * tape ,
618
+ SortTuple * stup );
621
619
static bool consider_abort_common (Tuplesortstate * state );
622
620
static void inittapes (Tuplesortstate * state , bool mergeruns );
623
621
static void inittapestate (Tuplesortstate * state , int maxTapes );
@@ -1848,7 +1846,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
1848
1846
/* copy the tuple into sort storage */
1849
1847
tuple = ExecCopySlotMinimalTuple (slot );
1850
1848
stup .tuple = (void * ) tuple ;
1851
- USEMEM (state , GetMemoryChunkSpace (tuple ));
1852
1849
/* set up first-column key value */
1853
1850
htup .t_len = tuple -> t_len + MINIMAL_TUPLE_OFFSET ;
1854
1851
htup .t_data = (HeapTupleHeader ) ((char * ) tuple - MINIMAL_TUPLE_OFFSET );
@@ -1857,8 +1854,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
1857
1854
state -> tupDesc ,
1858
1855
& stup .isnull1 );
1859
1856
1860
- MemoryContextSwitchTo (state -> sortcontext );
1861
-
1862
1857
puttuple_common (state , & stup ,
1863
1858
state -> sortKeys -> abbrev_converter && !stup .isnull1 );
1864
1859
@@ -1879,9 +1874,6 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
1879
1874
/* copy the tuple into sort storage */
1880
1875
tup = heap_copytuple (tup );
1881
1876
stup .tuple = (void * ) tup ;
1882
- USEMEM (state , GetMemoryChunkSpace (tup ));
1883
-
1884
- MemoryContextSwitchTo (state -> sortcontext );
1885
1877
1886
1878
/*
1887
1879
* set up first-column key value, and potentially abbreviate, if it's a
@@ -1910,27 +1902,21 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
1910
1902
ItemPointer self , Datum * values ,
1911
1903
bool * isnull )
1912
1904
{
1913
- MemoryContext oldcontext ;
1914
1905
SortTuple stup ;
1915
1906
IndexTuple tuple ;
1916
1907
1917
1908
stup .tuple = index_form_tuple_context (RelationGetDescr (rel ), values ,
1918
1909
isnull , state -> tuplecontext );
1919
1910
tuple = ((IndexTuple ) stup .tuple );
1920
1911
tuple -> t_tid = * self ;
1921
- USEMEM (state , GetMemoryChunkSpace (stup .tuple ));
1922
1912
/* set up first-column key value */
1923
1913
stup .datum1 = index_getattr (tuple ,
1924
1914
1 ,
1925
1915
RelationGetDescr (state -> indexRel ),
1926
1916
& stup .isnull1 );
1927
1917
1928
- oldcontext = MemoryContextSwitchTo (state -> sortcontext );
1929
-
1930
1918
puttuple_common (state , & stup ,
1931
1919
state -> sortKeys && state -> sortKeys -> abbrev_converter && !stup .isnull1 );
1932
-
1933
- MemoryContextSwitchTo (oldcontext );
1934
1920
}
1935
1921
1936
1922
/*
@@ -1965,15 +1951,12 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
1965
1951
stup .datum1 = !isNull ? val : (Datum ) 0 ;
1966
1952
stup .isnull1 = isNull ;
1967
1953
stup .tuple = NULL ; /* no separate storage */
1968
- MemoryContextSwitchTo (state -> sortcontext );
1969
1954
}
1970
1955
else
1971
1956
{
1972
1957
stup .isnull1 = false;
1973
1958
stup .datum1 = datumCopy (val , false, state -> datumTypeLen );
1974
1959
stup .tuple = DatumGetPointer (stup .datum1 );
1975
- USEMEM (state , GetMemoryChunkSpace (stup .tuple ));
1976
- MemoryContextSwitchTo (state -> sortcontext );
1977
1960
}
1978
1961
1979
1962
puttuple_common (state , & stup ,
@@ -1988,8 +1971,14 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
1988
1971
static void
1989
1972
puttuple_common (Tuplesortstate * state , SortTuple * tuple , bool useAbbrev )
1990
1973
{
1974
+ MemoryContext oldcontext = MemoryContextSwitchTo (state -> sortcontext );
1975
+
1991
1976
Assert (!LEADER (state ));
1992
1977
1978
+ /* Count the size of the out-of-line data */
1979
+ if (tuple -> tuple != NULL )
1980
+ USEMEM (state , GetMemoryChunkSpace (tuple -> tuple ));
1981
+
1993
1982
if (!useAbbrev )
1994
1983
{
1995
1984
/*
@@ -2062,14 +2051,18 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
2062
2051
pg_rusage_show (& state -> ru_start ));
2063
2052
#endif
2064
2053
make_bounded_heap (state );
2054
+ MemoryContextSwitchTo (oldcontext );
2065
2055
return ;
2066
2056
}
2067
2057
2068
2058
/*
2069
2059
* Done if we still fit in available memory and have array slots.
2070
2060
*/
2071
2061
if (state -> memtupcount < state -> memtupsize && !LACKMEM (state ))
2062
+ {
2063
+ MemoryContextSwitchTo (oldcontext );
2072
2064
return ;
2065
+ }
2073
2066
2074
2067
/*
2075
2068
* Nope; time to switch to tape-based operation.
@@ -2123,6 +2116,25 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
2123
2116
elog (ERROR , "invalid tuplesort state" );
2124
2117
break ;
2125
2118
}
2119
+ MemoryContextSwitchTo (oldcontext );
2120
+ }
2121
+
2122
+ /*
2123
+ * Write a stored tuple onto tape.tuple. Unless the slab allocator is
2124
+ * used, after writing the tuple, pfree() the out-of-line data (not the
2125
+ * SortTuple struct!), and increase state->availMem by the amount of
2126
+ * memory space thereby released.
2127
+ */
2128
+ static void
2129
+ writetuple (Tuplesortstate * state , LogicalTape * tape , SortTuple * stup )
2130
+ {
2131
+ state -> writetup (state , tape , stup );
2132
+
2133
+ if (!state -> slabAllocatorUsed && stup -> tuple )
2134
+ {
2135
+ FREEMEM (state , GetMemoryChunkSpace (stup -> tuple ));
2136
+ pfree (stup -> tuple );
2137
+ }
2126
2138
}
2127
2139
2128
2140
static bool
@@ -3960,12 +3972,6 @@ writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
3960
3972
if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
3961
3973
* word? */
3962
3974
LogicalTapeWrite (tape , (void * ) & tuplen , sizeof (tuplen ));
3963
-
3964
- if (!state -> slabAllocatorUsed )
3965
- {
3966
- FREEMEM (state , GetMemoryChunkSpace (tuple ));
3967
- heap_free_minimal_tuple (tuple );
3968
- }
3969
3975
}
3970
3976
3971
3977
static void
@@ -4141,12 +4147,6 @@ writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
4141
4147
if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
4142
4148
* word? */
4143
4149
LogicalTapeWrite (tape , & tuplen , sizeof (tuplen ));
4144
-
4145
- if (!state -> slabAllocatorUsed )
4146
- {
4147
- FREEMEM (state , GetMemoryChunkSpace (tuple ));
4148
- heap_freetuple (tuple );
4149
- }
4150
4150
}
4151
4151
4152
4152
static void
@@ -4403,12 +4403,6 @@ writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
4403
4403
if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
4404
4404
* word? */
4405
4405
LogicalTapeWrite (tape , (void * ) & tuplen , sizeof (tuplen ));
4406
-
4407
- if (!state -> slabAllocatorUsed )
4408
- {
4409
- FREEMEM (state , GetMemoryChunkSpace (tuple ));
4410
- pfree (tuple );
4411
- }
4412
4406
}
4413
4407
4414
4408
static void
@@ -4495,12 +4489,6 @@ writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
4495
4489
if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
4496
4490
* word? */
4497
4491
LogicalTapeWrite (tape , (void * ) & writtenlen , sizeof (writtenlen ));
4498
-
4499
- if (!state -> slabAllocatorUsed && stup -> tuple )
4500
- {
4501
- FREEMEM (state , GetMemoryChunkSpace (stup -> tuple ));
4502
- pfree (stup -> tuple );
4503
- }
4504
4492
}
4505
4493
4506
4494
static void
0 commit comments