This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch TIKA-4868-performance-improvements
in repository https://gitbox.apache.org/repos/asf/tika.git

commit 967e988c59b956d923b9ffdbf1b0c4eaac86a05b
Author: tallison <[email protected]>
AuthorDate: Wed Sep 2 08:11:29 2026 -0400

    fix zip rewind re-decompression
---
 CHANGES.txt                                                |  8 ++++++++
 .../main/java/org/apache/tika/parser/pkg/ZipParser.java    | 14 +++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 0e6e1ad587..7744bb009c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,13 @@
 Release 4.1.0 - unreleased
 
+   * ZipParser no longer re-decompresses an entry on every rewind when the
+     entry uses a legacy compression method (implode, shrink, bzip2, ...):
+     those decode per-bit, so the rewind-by-reopen trade that works for
+     STORED/DEFLATED entries re-decoded the whole entry for each of the
+     several rewinds the embedded pipeline performs. Such entries now
+     replay from the budgeted cache. An imploded 606KB zip drops from
+     610ms to 102ms in tika-server (TIKA-4868).
+
    * More detection/dispatch savings: the message/rfc822 priority-45 magic
      is gated behind a ':' scan of the first 30 bytes (every match provably
      has one, so results are unchanged and non-mail text skips its ~40
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/ZipParser.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/ZipParser.java
index 58e703d79d..405bb314bb 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/ZipParser.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/ZipParser.java
@@ -497,9 +497,17 @@ public class ZipParser extends AbstractArchiveParser {
         if (extractor.shouldParseEmbedded(entryMetadata, context)) {
             TemporaryResources tmp = new TemporaryResources();
             // Re-openable source: rewind (e.g. for digesting) re-opens the 
entry instead of
-            // buffering/spilling it
-            try (TikaInputStream tis = TikaInputStream.get(
-                    () -> zipFile.getInputStream(entry), tmp, entryMetadata)) {
+            // buffering/spilling it. That trade only holds when re-opening is 
cheap --
+            // STORED and DEFLATED. The legacy methods (implode, shrink, 
bzip2, ...) decode
+            // per-bit, so a re-open re-decompresses the whole entry for every 
rewind;
+            // those route through the budgeted cache instead (memory up to the
+            // CacheMemoryBudget, temp spill beyond it).
+            int method = entry.getMethod();
+            boolean cheapReopen = method == java.util.zip.ZipEntry.STORED
+                    || method == java.util.zip.ZipEntry.DEFLATED;
+            try (TikaInputStream tis = cheapReopen
+                    ? TikaInputStream.get(() -> zipFile.getInputStream(entry), 
tmp, entryMetadata)
+                    : TikaInputStream.get(zipFile.getInputStream(entry), tmp, 
entryMetadata)) {
                 extractor.parseEmbedded(tis, xhtml, entryMetadata, context, 
true);
             } catch (UnsupportedZipFeatureException e) {
                 EmbeddedDocumentUtil.recordEmbeddedStreamException(e, 
parentMetadata, context);

Reply via email to