From 1e1a5a1443dd50f6148df1a936d3f43fadee96f7 Mon Sep 17 00:00:00 2001 From: Edgar Asatryan Date: Sun, 3 Apr 2022 19:40:11 +0400 Subject: [PATCH] chore(perf): Store Cipher instance in ThreadLocal. --- .../http/ext/EncryptedStreamFactory.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/nstdio/http/ext/EncryptedStreamFactory.java b/src/main/java/io/github/nstdio/http/ext/EncryptedStreamFactory.java index 25607f3..16fe208 100644 --- a/src/main/java/io/github/nstdio/http/ext/EncryptedStreamFactory.java +++ b/src/main/java/io/github/nstdio/http/ext/EncryptedStreamFactory.java @@ -21,7 +21,6 @@ import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; -import javax.crypto.NoSuchPaddingException; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -49,6 +48,7 @@ class EncryptedStreamFactory implements StreamFactory { private final String transformation; private final String algorithm; private final String provider; + private final ThreadLocal threadLocalCipher; public EncryptedStreamFactory(StreamFactory delegate, Key publicKey, Key privateKey, String transformation, String provider) { this.delegate = delegate; @@ -57,6 +57,7 @@ public EncryptedStreamFactory(StreamFactory delegate, Key publicKey, Key private this.transformation = transformation; this.algorithm = algo(transformation); this.provider = provider; + this.threadLocalCipher = new ThreadLocal<>(); } private static String algo(String transformation) { @@ -64,12 +65,25 @@ private static String algo(String transformation) { return i == -1 ? transformation : transformation.substring(0, i); } - private Cipher cipher() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException { + @SneakyThrows + private Cipher createCipher() { return hasProvider() ? Cipher.getInstance(transformation, provider) : Cipher.getInstance(transformation); } + private Cipher cipher() { + var thCipher = threadLocalCipher; + + if (thCipher.get() == null) { + var cipher = createCipher(); + thCipher.set(cipher); + return cipher; + } + + return thCipher.get(); + } + private boolean hasProvider() { return provider != null; }