https://bugs.kde.org/show_bug.cgi?id=470654

[email protected] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #4 from [email protected] ---
Re-confirming this on the current release, with measurements, and I think I
have the root cause.

Tested on CachyOS, ark 26.08.1-1.1 (libarchive backend for tar.*, libzip for
zip, cli7z for 7z).

Method: gdb, "break _ZN4KJob10setPercentEm" (KJob::setPercent lives in
libKF6CoreAddons, value in $rsi, object in $rdi), logging only calls where
$rdi is the BatchExtractJob instance. This matters -- the inner LoadJob and
ExtractJob each call setPercent on themselves via the base Job::onProgress,
so a breakpoint that does not filter to the BatchExtractJob will report them
too and produce a misleading "49/99 alternation".

Final value BatchExtractJob::percent reaches, stock build:

  test.tar.zst (406 entries, 191 MiB)      -> 80
  test.tar.gz  (406 entries)               -> 80
  test.tar.zst (20,004 small files)        -> 50
  test.zip     (libzip backend)            -> 100

All four are monotonic. The bar is not restarting or ping-ponging -- it is
reaching a ceiling and stopping there. That matches Fabian's report above
(".tar.zst jumps to 50% and no progress", "ends at 50% and is finished
afterwards"), so I think this and 382599 are the same underlying defect.

Root cause: BatchExtractJob reserves 0-50% for the listing phase and
50-100% for extraction, and joins the two halves with one field:

  void BatchExtractJob::slotExtractProgress(double progress)
  {
      setPercent(m_lastPercentage + static_cast<unsigned long>(50.0 *
progress));
  }

m_lastPercentage is written by slotLoadingProgress() from the backend's
*listing* pass. So the bar's ceiling for the whole extraction is
m_lastPercentage + 50, where m_lastPercentage is a number with no
relationship to how much extraction work is left.

That gives both failure modes reported here:
 - high bogus listing value -> bar parked at 80% for the entire extraction
   (libarchive reports ~0.6 for test.tar.zst, m_lastPercentage = 30)
 - low bogus listing value -> bar capped at 50% (the 20,004-small-file
   archive, where the listing metric stays near 0)

The extraction denominator itself is fine: libarchiveplugin.cpp:188 uses
m_currentExtractedFilesSize / m_extractedFilesSize, and SUM_ENTRY_SIZE
matches the bytes actually written. The shortfall is entirely the inflated
base.

libarchive's listing metric is archive_filter_bytes(a, -1), i.e. read
position relative to archive file size, not entries processed. For
test.tar.zst it sits around 0.10 for 400 of the 406 entries and then jumps
to 1.0 at the end -- consistent with the existing TODO at
libarchiveplugin.cpp:264.

Fix I have working: set m_lastPercentage = 50 in slotLoadingFinished()
instead of inheriting the listing value, clamp both slots' input to 0..1,
clamp to <= 100, and never let the reported value decrease. With that, all
three tar.* cases above go 0 -> 50 -> 51 -> ... -> 100, monotonically, and
the 21 ctest cases pass.

Happy to submit an MR -- which branch would you prefer, release/26.08 or
master?

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to