@@ -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 }
0 commit comments