Skip to content

Commit 9f6f708

Browse files
committed
Optimized the post-processor's message sorting
Previously, the post-processor used std::sort to organize the log messages into a chronological order. This proved to be very expensive as the number of log messages to sort increased. This commit changes the post-processor to use std::*_heap operations instead.
1 parent 7c61777 commit 9f6f708

2 files changed

Lines changed: 37 additions & 16 deletions

File tree

runtime/Log.cc

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,27 @@ Log::Decoder::internalDecompressUnordered(FILE* outputFd,
17601760
return good;
17611761
}
17621762

1763+
1764+
/**
1765+
* Compares two BufferFragments (a, b) based on the timestamps of
1766+
* their next decompress-able log statements. Returns true if
1767+
* a's timestamp chronologically occurs after b's timestamp.
1768+
*
1769+
* \param a
1770+
* First BufferFragment to compare
1771+
* \param b
1772+
* Second BufferFragment to compare
1773+
*
1774+
* \return
1775+
* True if a > b; False otherwise
1776+
*/
1777+
bool
1778+
Log::Decoder::compareBufferFragments(const BufferFragment *a,
1779+
const BufferFragment *b)
1780+
{
1781+
return a->getNextLogTimestamp() > b->getNextLogTimestamp();
1782+
};
1783+
17631784
/**
17641785
* Decompress the log file that was open()-ed and print the log messages out
17651786
* in chronological order.
@@ -1861,14 +1882,10 @@ Log::Decoder::decompressTo(FILE* outputFd)
18611882
break;
18621883
}
18631884

1864-
// Step 2: Sort all BufferFragments within the stages from
1885+
// Step 2: Heapify all BufferFragments within the stages from
18651886
// front=max to back=min
18661887
for (auto &stage : stages) {
1867-
std::sort(stage.begin(), stage.end(),
1868-
[](const BufferFragment *a, const BufferFragment *b) -> bool
1869-
{
1870-
return a->getNextLogTimestamp() > b->getNextLogTimestamp();
1871-
});
1888+
std::make_heap(stage.begin(), stage.end(), compareBufferFragments);
18721889
}
18731890

18741891
// Step 3: Deplete the first stage
@@ -1879,9 +1896,9 @@ Log::Decoder::decompressTo(FILE* outputFd)
18791896
if (stages[i].empty())
18801897
continue;
18811898

1882-
uint64_t next = stages[i].back()->getNextLogTimestamp();
1899+
uint64_t next = stages[i].front()->getNextLogTimestamp();
18831900
if (minStage == nullptr ||
1884-
next < minStage->back()->getNextLogTimestamp()) {
1901+
next < minStage->front()->getNextLogTimestamp()) {
18851902
minStage = &(stages[i]);
18861903
}
18871904
}
@@ -1891,20 +1908,21 @@ Log::Decoder::decompressTo(FILE* outputFd)
18911908
break;
18921909

18931910
// Step 3b: Output the log message
1894-
BufferFragment *bf = minStage->back();
1911+
BufferFragment *bf = minStage->front();
18951912
bf->decompressNextLogStatement(outputFd, logMsgsPrinted,
18961913
logArguments, checkpoint,
18971914
fmtId2metadata);
18981915

1916+
// Moves the minimum element to the end of the array
1917+
std::pop_heap(minStage->begin(), minStage->end(),
1918+
compareBufferFragments);
1919+
18991920
if (bf->hasNext()) {
1900-
std::sort(minStage->begin(), minStage->end(),
1901-
[](const BufferFragment *a, const BufferFragment *b) -> bool
1902-
{
1903-
return a->getNextLogTimestamp() >
1904-
b->getNextLogTimestamp();
1905-
});
1921+
// If there's more, re-heapify the last element
1922+
std::push_heap(minStage->begin(), minStage->end(),
1923+
compareBufferFragments);
19061924
} else {
1907-
// Buffer is depleted, remove it
1925+
// Otherwise, buffer is depleted -> remove it
19081926
minStage->pop_back();
19091927
freeBufferFragment(bf);
19101928
}

runtime/Log.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,9 @@ namespace Log {
903903
uint64_t getNextLogTimestamp() const;
904904
};
905905

906+
static bool compareBufferFragments(const BufferFragment *a,
907+
const BufferFragment *b);
908+
906909
bool readDictionary(FILE *fd, bool flushOldDictionary);
907910
bool readDictionaryFragment(FILE *fd);
908911

0 commit comments

Comments
 (0)