"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/sort.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

sort.cpp  (Firebird-3.0.2.32703-0.tar.bz2):sort.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 387 skipping to change at line 387
diddleKey((UCHAR*) (record->sr_sort_record.sort_record_ke y), true); diddleKey((UCHAR*) (record->sr_sort_record.sort_record_ke y), true);
} }
// If there isn't room for the record, sort and write the run. // If there isn't room for the record, sort and write the run.
// Check that we are not at the beginning of the buffer in additi on // Check that we are not at the beginning of the buffer in additi on
// to checking for space for the record. This avoids the pointer // to checking for space for the record. This avoids the pointer
// record from underflowing in the second condition. // record from underflowing in the second condition.
if ((UCHAR*) record < m_memory + m_longs || if ((UCHAR*) record < m_memory + m_longs ||
(UCHAR*) NEXT_RECORD(record) <= (UCHAR*) (m_next_pointer + 1)) (UCHAR*) NEXT_RECORD(record) <= (UCHAR*) (m_next_pointer + 1))
{ {
putRun(); putRun(tdbb);
while (true) while (true)
{ {
run_control* run = m_runs; run_control* run = m_runs;
const USHORT depth = run->run_depth; const USHORT depth = run->run_depth;
if (depth == MAX_MERGE_LEVEL) if (depth == MAX_MERGE_LEVEL)
break; break;
USHORT count = 1; USHORT count = 1;
while ((run = run->run_next) && run->run_depth == depth) while ((run = run->run_next) && run->run_depth == depth)
count++; count++;
if (count < RUN_GROUP) if (count < RUN_GROUP)
skipping to change at line 454 skipping to change at line 454
{ {
if (m_last_record != (SR*) m_end_memory) if (m_last_record != (SR*) m_end_memory)
{ {
diddleKey((UCHAR*) KEYOF(m_last_record), true); diddleKey((UCHAR*) KEYOF(m_last_record), true);
} }
// If there aren't any runs, things fit nicely in memory. Just so rt the mess // If there aren't any runs, things fit nicely in memory. Just so rt the mess
// and we're ready for output. // and we're ready for output.
if (!m_runs) if (!m_runs)
{ {
sort(); sortBuffer(tdbb);
m_next_pointer = m_first_pointer + 1; m_next_pointer = m_first_pointer + 1;
m_flags |= scb_sorted; m_flags |= scb_sorted;
return; return;
} }
// Write the last records as a run_control // Write the last records as a run_control
putRun(); putRun(tdbb);
CHECK_FILE(NULL); CHECK_FILE(NULL);
// Merge runs of low depth to free memory part of temp space // Merge runs of low depth to free memory part of temp space
// they use and to make total runs count lower. This is fast // they use and to make total runs count lower. This is fast
// because low depth runs usually sit in memory // because low depth runs usually sit in memory
ULONG run_count = 0, low_depth_cnt = 0; ULONG run_count = 0, low_depth_cnt = 0;
for (run = m_runs; run; run = run->run_next) for (run = m_runs; run; run = run->run_next)
{ {
++run_count; ++run_count;
skipping to change at line 497 skipping to change at line 497
for (run_count = 0, run = m_runs; run; run = run->run_next) for (run_count = 0, run = m_runs; run; run = run->run_next)
{ {
if (run->run_buff_alloc) if (run->run_buff_alloc)
{ {
delete[] run->run_buffer; delete[] run->run_buffer;
run->run_buff_alloc = false; run->run_buff_alloc = false;
} }
++run_count; ++run_count;
} }
AutoPtr<run_merge_hdr*, ArrayDelete<run_merge_hdr*> &gt; streams( AutoPtr<run_merge_hdr*, ArrayDelete> streams(
FB_NEW_POOL(m_owner->getPool()) run_merge_hdr*[run_count] ); FB_NEW_POOL(m_owner->getPool()) run_merge_hdr*[run_count] );
run_merge_hdr** m1 = streams; run_merge_hdr** m1 = streams;
for (run = m_runs; run; run = run->run_next) for (run = m_runs; run; run = run->run_next)
*m1++ = (run_merge_hdr*) run; *m1++ = (run_merge_hdr*) run;
ULONG count = run_count; ULONG count = run_count;
// We're building a b-tree of the sort merge blocks, we have (cou nt) // We're building a b-tree of the sort merge blocks, we have (cou nt)
// leaves already, so we *know* we need (count-1) merge blocks. // leaves already, so we *know* we need (count-1) merge blocks.
skipping to change at line 1794 skipping to change at line 1794
lower_limit = (sort_ptr_t*) ((SORTP*) lower_limit + m_longs); lower_limit = (sort_ptr_t*) ((SORTP*) lower_limit + m_longs);
MOVE_32(length, buffer, output); MOVE_32(length, buffer, output);
output = reinterpret_cast<sort_record*>((sort_ptr_t*) ((SORTP*) o utput + length)); output = reinterpret_cast<sort_record*>((sort_ptr_t*) ((SORTP*) o utput + length));
} }
return (((SORTP*) output) - return (((SORTP*) output) -
((SORTP*) m_last_record)) / (m_longs - SIZEOF_SR_BCKPTR_I N_LONGS); ((SORTP*) m_last_record)) / (m_longs - SIZEOF_SR_BCKPTR_I N_LONGS);
} }
void Sort::orderAndSave() void Sort::orderAndSave(thread_db* tdbb)
{ {
/************************************** /**************************************
* *
* The memory full of record pointers has been sorted, but more * The memory full of record pointers has been sorted, but more
* records remain, so the run will have to be written to scratch file. * records remain, so the run will have to be written to scratch file.
* If target run can be allocated in contiguous chunk of memory then * If target run can be allocated in contiguous chunk of memory then
* just memcpy records into it. Else call more expensive order() to * just memcpy records into it. Else call more expensive order() to
* physically rearrange records in sort space and write its run into * physically rearrange records in sort space and write its run into
* scratch file as one big chunk * scratch file as one big chunk
* *
**************************************/ **************************************/
EngineCheckout(tdbb, FB_FUNCTION);
run_control* run = m_runs; run_control* run = m_runs;
run->run_records = 0; run->run_records = 0;
sort_record** ptr = m_first_pointer + 1; // 1st ptr is low key sort_record** ptr = m_first_pointer + 1; // 1st ptr is low key
// m_next_pointer points to the end of pointer memory or the beginning of records // m_next_pointer points to the end of pointer memory or the beginning of records
while (ptr < m_next_pointer) while (ptr < m_next_pointer)
{ {
// If the next pointer is null, it's record has been eliminated a s a // If the next pointer is null, it's record has been eliminated a s a
// duplicate. This is the only easy case. // duplicate. This is the only easy case.
if (!(*ptr++)) if (!(*ptr++))
skipping to change at line 1852 skipping to change at line 1854
mem += key_length; mem += key_length;
} }
} }
else else
{ {
order(); order();
writeBlock(m_space, run->run_seek, (UCHAR*) m_last_record, run->r un_size); writeBlock(m_space, run->run_seek, (UCHAR*) m_last_record, run->r un_size);
} }
} }
void Sort::putRun() void Sort::putRun(thread_db* tdbb)
{ {
/************************************** /**************************************
* *
* Memory has been exhausted. Do a sort on what we have and write * Memory has been exhausted. Do a sort on what we have and write
* it to the scratch file. Keep in mind that since duplicate records * it to the scratch file. Keep in mind that since duplicate records
* may disappear, the number of records in the run may be less than * may disappear, the number of records in the run may be less than
* were sorted. * were sorted.
* *
**************************************/ **************************************/
run_control* run = m_free_runs; run_control* run = m_free_runs;
skipping to change at line 1880 skipping to change at line 1882
memset(run, 0, sizeof(run_control)); memset(run, 0, sizeof(run_control));
run->run_next = m_runs; run->run_next = m_runs;
m_runs = run; m_runs = run;
run->run_header.rmh_type = RMH_TYPE_RUN; run->run_header.rmh_type = RMH_TYPE_RUN;
run->run_depth = 0; run->run_depth = 0;
// Do the in-core sort. The first phase a duplicate handling we be perfor med // Do the in-core sort. The first phase a duplicate handling we be perfor med
// in "sort". // in "sort".
sort(); sortBuffer(tdbb);
// Re-arrange records in physical order so they can be dumped in a single write // Re-arrange records in physical order so they can be dumped in a single write
// operation // operation
orderAndSave(); orderAndSave(tdbb);
} }
void Sort::sort() void Sort::sortBuffer(thread_db* tdbb)
{ {
/************************************** /**************************************
* *
* Set up for and call quick sort. Quicksort, by design, doesn't * Set up for and call quick sort. Quicksort, by design, doesn't
* order partitions of length 2, so make a pass thru the data to * order partitions of length 2, so make a pass thru the data to
* straighten out pairs. While we at it, if duplicate handling has * straighten out pairs. While we at it, if duplicate handling has
* been requested, detect and handle them. * been requested, detect and handle them.
* *
**************************************/ **************************************/
EngineCheckout(tdbb, FB_FUNCTION);
// First, insert a pointer to the high key // First, insert a pointer to the high key
*m_next_pointer = reinterpret_cast<sort_record*>(high_key); *m_next_pointer = reinterpret_cast<sort_record*>(high_key);
// Next, call QuickSort. Keep in mind that the first pointer is the // Next, call QuickSort. Keep in mind that the first pointer is the
// low key and not a record. // low key and not a record.
SORTP** j = (SORTP**) (m_first_pointer) + 1; SORTP** j = (SORTP**) (m_first_pointer) + 1;
const ULONG n = (SORTP**) (m_next_pointer) - j; // calculate # of records const ULONG n = (SORTP**) (m_next_pointer) - j; // calculate # of records
 End of changes. 11 change blocks. 
9 lines changed or deleted 12 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)