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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 373ee83d [COMPRESS-649] Improve performance in 
org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorOutputStream.Pair.literalLength()
     new 10bc9ff2 Merge branch 'master' of 
https://gitbox.apache.org/repos/asf/commons-compress.git
373ee83d is described below

commit 373ee83d801cf635319cd74e35d8abbd0062e1ea
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Fri Oct 27 07:04:40 2023 -0400

    [COMPRESS-649] Improve performance in
    
org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorOutputStream.Pair.literalLength()
---
 src/changes/changes.xml                            |  2 +
 .../lz4/BlockLZ4CompressorOutputStream.java        | 14 ++++-
 .../lz4/CompressionDegradationTest.java            | 73 ++++++++++++++++++++++
 .../compress/COMPRESS-649/some-900kb-text.txt      |  1 +
 4 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index b560d1ca..4f81835e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -68,6 +68,8 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Precompile 
regular expression in ArArchiveInputStream.isGNULongName(String).</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Precompile 
regular expression in 
TarArchiveEntry.parseInstantFromDecimalSeconds(String).</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Precompile 
regular expression in ChangeSet.addDeletion(Change).</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory" 
issue="COMPRESS-649">Improve performance in 
BlockLZ4CompressorOutputStream.</action>
+      
       <!-- UPDATE -->
       <action type="update" dev="ggregory" due-to="Dependabot">Bump 
org.slf4j:slf4j-api from 2.0.8 to 2.0.9 #413.</action>
       <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
commons-io:commons-io from 2.13.0 to 2.15.0.</action>
diff --git 
a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java
 
b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java
index 4190cb22..eea19f10 100644
--- 
a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java
+++ 
b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorOutputStream.java
@@ -53,6 +53,8 @@ public class BlockLZ4CompressorOutputStream extends 
CompressorOutputStream {
             out.write(length);
         }
         private final Deque<byte[]> literals = new LinkedList<>();
+        
+        private int literalLength;
 
         private int brOffset, brLength;
 
@@ -62,6 +64,7 @@ public class BlockLZ4CompressorOutputStream extends 
CompressorOutputStream {
             final byte[] copy = Arrays.copyOfRange(block.getData(), 
block.getOffset(),
                 block.getOffset() + block.getLength());
             literals.add(copy);
+            literalLength += copy.length;
             return copy;
         }
 
@@ -87,11 +90,20 @@ public class BlockLZ4CompressorOutputStream extends 
CompressorOutputStream {
         }
 
         private int literalLength() {
-            return literals.stream().mapToInt(b -> b.length).sum();
+            // This method is performance sensitive
+            if (literalLength != 0) {
+                return literalLength;
+            }
+            int length = 0;
+            for (final byte[] b : literals) {
+                length += b.length;
+            }
+            return literalLength = length;
         }
 
         private void prependLiteral(final byte[] data) {
             literals.addFirst(data);
+            literalLength += data.length;
         }
 
         private void prependTo(final Pair other) {
diff --git 
a/src/test/java/org/apache/commons/compress/compressors/lz4/CompressionDegradationTest.java
 
b/src/test/java/org/apache/commons/compress/compressors/lz4/CompressionDegradationTest.java
new file mode 100644
index 00000000..653825dc
--- /dev/null
+++ 
b/src/test/java/org/apache/commons/compress/compressors/lz4/CompressionDegradationTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.lz4;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+/**
+ * Tests COMPRESS-649.
+ */
+public class CompressionDegradationTest {
+
+    public static void main(final String[] args) throws Exception {
+        try (RandomAccessFile aFile = new 
RandomAccessFile("src/test/resources/org/apache/commons/compress/COMPRESS-649/some-900kb-text.txt",
 "r");
+                FileChannel inChannel = aFile.getChannel()) {
+            final long fileSize = inChannel.size();
+
+            final ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
+            inChannel.read(buffer);
+            buffer.flip();
+
+            final String rawPlan = new String(buffer.array(), 
StandardCharsets.UTF_8);
+            final long start = System.currentTimeMillis();
+            for (int i = 0; i < 80; i++) {
+                assertNotNull(compress(rawPlan));
+            }
+            final long end = System.currentTimeMillis();
+            final float sec = (end - start) / 1000F;
+            System.out.println(sec + " seconds");
+        }
+    }
+
+    private static String compress(final String value) throws IOException {
+        try (ByteArrayOutputStream byteStream = new 
ByteArrayOutputStream(value.length());
+                FramedLZ4CompressorOutputStream compress = new 
FramedLZ4CompressorOutputStream(byteStream)) {
+            String compressedValue = null;
+            try {
+                compress.write(value.getBytes(StandardCharsets.UTF_8));
+                compress.finish();
+                compressedValue = 
Base64.getEncoder().encodeToString(byteStream.toByteArray());
+            } finally {
+                compress.close();
+                byteStream.close();
+            }
+
+            return compressedValue;
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/src/test/resources/org/apache/commons/compress/COMPRESS-649/some-900kb-text.txt
 
b/src/test/resources/org/apache/commons/compress/COMPRESS-649/some-900kb-text.txt
new file mode 100644
index 00000000..dc323a58
--- /dev/null
+++ 
b/src/test/resources/org/apache/commons/compress/COMPRESS-649/some-900kb-text.txt
@@ -0,0 +1 @@
+5EUUBnKi7eAidloprJ6kOXt0C4Biy0GwHUnlThbHPe6hyNkGQTE9ZfFLOzqniL0BDKgaCVHa8GqWVDw6nZBoJC0i6RwjcbeHkk512gLbXji6sQ1D0oQvSBmGBONnRiaLcRShW3QOr1F4rlVCOxva92ENoiW2lclQN92YJLm5t1MRSAuxpon8qn52kvxImHyyBavAcujZC22GgZ8sIuPZwN6XC1JOlgDQVzNQYI0nFaBVVYTe4tLfbtTOpj10flv3DpewXRLzJIVjhFzPRy0SjoZgQBZFnZIFn52V6CaxqVLfMMosq93U0A4xqnmEvjnWIjhHVsltWItaHgd6DU5gVGLhClRFqqkbXUQou9XHmcGFmj5GP0wbXnvZIvcHVmO3lNaWrCyf1yf3aIGGkWRezOz9AYWK5hRf8r5LAdpu8mMlPc0PSO74uGK6sPRze6l5xzDpUtraiDcWfLfz1F81Rc4qs5rtfNciJXUN3Ltp8UsX
 [...]
\ No newline at end of file

Reply via email to