@@ -68,12 +68,6 @@ const USHORT MAX_MERGE_LEVEL = 2;
68
68
using namespace Jrd ;
69
69
using namespace Firebird ;
70
70
71
- void SortOwner::unlinkAll ()
72
- {
73
- while (sorts.getCount ())
74
- delete sorts.pop ();
75
- }
76
-
77
71
// The sort buffer size should be just under a multiple of the
78
72
// hardware memory page size to account for memory allocator
79
73
// overhead. On most platforms, this saves 4KB to 8KB per sort
@@ -165,10 +159,11 @@ Sort::Sort(Database* dbb,
165
159
FPTR_REJECT_DUP_CALLBACK call_back,
166
160
void * user_arg,
167
161
FB_UINT64 max_records)
168
- : m_dbb(dbb), m_last_record(NULL ), m_next_pointer(NULL ), m_records(0 ),
162
+ : m_dbb(dbb), m_owner(owner),
163
+ m_last_record(NULL ), m_next_pointer(NULL ), m_records(0 ),
169
164
m_runs(NULL ), m_merge(NULL ), m_free_runs(NULL ),
170
165
m_flags(0 ), m_merge_pool(NULL ),
171
- m_description(owner ->getPool (), keys)
166
+ m_description(m_owner ->getPool (), keys)
172
167
{
173
168
/* *************************************
174
169
*
@@ -185,7 +180,7 @@ Sort::Sort(Database* dbb,
185
180
* includes index key (which must be unique) and record numbers.
186
181
*
187
182
**************************************/
188
- fb_assert (owner );
183
+ fb_assert (m_owner );
189
184
fb_assert (unique_keys <= keys);
190
185
191
186
try
@@ -194,7 +189,7 @@ Sort::Sort(Database* dbb,
194
189
// key description vector. Round the record length up to the next
195
190
// longword, and add a longword to a pointer back to the pointer slot.
196
191
197
- MemoryPool& pool = owner ->getPool ();
192
+ MemoryPool& pool = m_owner ->getPool ();
198
193
199
194
const ULONG record_size = ROUNDUP (record_length + SIZEOF_SR_BCKPTR, FB_ALIGNMENT);
200
195
m_longs = record_size >> SHIFTLONG;
@@ -248,8 +243,7 @@ Sort::Sort(Database* dbb,
248
243
249
244
// Link in new sort block
250
245
251
- m_owner = owner;
252
- owner->linkSort (this );
246
+ m_owner->linkSort (this );
253
247
}
254
248
catch (const BadAlloc&)
255
249
{
@@ -610,15 +604,12 @@ void Sort::sort(thread_db* tdbb)
610
604
611
605
void Sort::allocateBuffer (MemoryPool& pool)
612
606
{
613
- if (m_dbb-> dbb_sort_buffers . hasData () && m_max_alloc_size <= MAX_SORT_BUFFER_SIZE)
607
+ if (m_max_alloc_size <= MAX_SORT_BUFFER_SIZE)
614
608
{
615
- SyncLockGuard guard (&m_dbb->dbb_sortbuf_sync , SYNC_EXCLUSIVE, " Sort::allocateBuffer" );
616
-
617
- if (m_dbb->dbb_sort_buffers .hasData ())
609
+ m_memory = m_owner->allocateBuffer ();
610
+ if (m_memory)
618
611
{
619
- // The sort buffer cache has at least one big block, let's use it
620
612
m_size_memory = MAX_SORT_BUFFER_SIZE;
621
- m_memory = m_dbb->dbb_sort_buffers .pop ();
622
613
m_flags |= scb_reuse_buffer;
623
614
return ;
624
615
}
@@ -666,23 +657,14 @@ void Sort::allocateBuffer(MemoryPool& pool)
666
657
667
658
void Sort::releaseBuffer ()
668
659
{
669
- // Here we cache blocks to be reused later, but only the biggest ones
670
-
671
- const size_t MAX_CACHED_SORT_BUFFERS = 8 ; // 1MB
672
-
673
- SyncLockGuard guard (&m_dbb->dbb_sortbuf_sync , SYNC_EXCLUSIVE, " Sort::releaseBuffer" );
674
-
675
- if ((m_flags & scb_reuse_buffer) &&
676
- m_dbb->dbb_sort_buffers .getCount () < MAX_CACHED_SORT_BUFFERS)
660
+ if (m_flags & scb_reuse_buffer)
677
661
{
678
662
fb_assert (m_size_memory == MAX_SORT_BUFFER_SIZE);
679
-
680
- m_dbb-> dbb_sort_buffers . push (m_memory);
663
+ m_flags &= ~scb_reuse_buffer;
664
+ m_owner-> releaseBuffer (m_memory);
681
665
}
682
666
else
683
667
delete[] m_memory;
684
-
685
- m_flags &= ~scb_reuse_buffer;
686
668
}
687
669
688
670
@@ -2181,6 +2163,53 @@ void Sort::sortRunsBySeek(int n)
2181
2163
}
2182
2164
2183
2165
2166
+ // / class SortOwner
2167
+
2168
+ UCHAR* SortOwner::allocateBuffer ()
2169
+ {
2170
+ if (buffers.hasData ())
2171
+ return buffers.pop ();
2172
+
2173
+ if (dbb->dbb_sort_buffers .hasData ())
2174
+ {
2175
+ SyncLockGuard guard (&dbb->dbb_sortbuf_sync , SYNC_EXCLUSIVE, FB_FUNCTION);
2176
+
2177
+ // The sort buffer cache has at least one big block, let's use it
2178
+ if (dbb->dbb_sort_buffers .hasData ())
2179
+ return dbb->dbb_sort_buffers .pop ();
2180
+ }
2181
+
2182
+ return nullptr ;
2183
+ }
2184
+
2185
+ void SortOwner::releaseBuffer (UCHAR* memory)
2186
+ {
2187
+ buffers.push (memory);
2188
+ }
2189
+
2190
+
2191
+ void SortOwner::unlinkAll ()
2192
+ {
2193
+ while (sorts.getCount ())
2194
+ delete sorts.pop ();
2195
+
2196
+ if (buffers.hasData ())
2197
+ {
2198
+ // Move cached buffers to the database level cache to be reused later by other attachments
2199
+
2200
+ const size_t MAX_CACHED_SORT_BUFFERS = 8 ; // 1MB
2201
+
2202
+ SyncLockGuard guard (&dbb->dbb_sortbuf_sync , SYNC_EXCLUSIVE, FB_FUNCTION);
2203
+
2204
+ while (buffers.hasData () && dbb->dbb_sort_buffers .getCount () < MAX_CACHED_SORT_BUFFERS)
2205
+ dbb->dbb_sort_buffers .push (buffers.pop ());
2206
+ }
2207
+
2208
+ while (buffers.hasData ())
2209
+ delete[] buffers.pop ();
2210
+ }
2211
+
2212
+
2184
2213
// / class PartitionedSort
2185
2214
2186
2215
0 commit comments