TAP5-2687: optimize AssetChecksumGeneratorImpl
to avoid storing whole StreamableResource instances in its cache. In
addition, use computeIfAbsent() instead of put() to avoid the
possibility of duplicate entries in the cache.
Also:
* StreamableResourceImpl now implements hashCode() and equals()
* ContentType used to implement just equals() and now implements
hashCode()
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
index f8b8c88..724fc0d 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
@@ -33,7 +33,7 @@
private final ResourceChangeTracker tracker;
- private final Map<StreamableResource, String> cache = CollectionFactory.newConcurrentMap();
+ private final Map<Integer, String> cache = CollectionFactory.newConcurrentMap();
public AssetChecksumGeneratorImpl(StreamableResourceSource streamableResourceSource, ResourceChangeTracker tracker)
{
@@ -53,16 +53,14 @@
public String generateChecksum(StreamableResource resource) throws IOException
{
- String result = cache.get(resource);
-
- if (result == null)
- {
- result = toChecksum(resource.openStream());
-
- cache.put(resource, result);
- }
-
- return result;
+ return cache.computeIfAbsent(resource.hashCode(),
+ r -> {
+ try {
+ return toChecksum(resource.openStream());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
}
private String toChecksum(InputStream is) throws IOException
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java
index 8c10d1c..76fe12b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Objects;
public class StreamableResourceImpl implements StreamableResource
{
@@ -136,4 +137,28 @@
{
return new StreamableResourceImpl(description, contentType, compression, lastModified, bytestreamCache, assetChecksumGenerator, customizer);
}
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(bytestreamCache.size(), compression, contentType, description, lastModified);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof StreamableResourceImpl))
+ {
+ return false;
+ }
+ StreamableResourceImpl other = (StreamableResourceImpl) obj;
+ return Objects.equals(bytestreamCache.size(), other.bytestreamCache.size()) && compression == other.compression && Objects.equals(contentType, other.contentType)
+ && Objects.equals(description, other.description) && lastModified == other.lastModified;
+ }
+
+
}
diff --git a/tapestry-http/src/main/java/org/apache/tapestry5/http/ContentType.java b/tapestry-http/src/main/java/org/apache/tapestry5/http/ContentType.java
index 0c8b01a..bf5da4a 100644
--- a/tapestry-http/src/main/java/org/apache/tapestry5/http/ContentType.java
+++ b/tapestry-http/src/main/java/org/apache/tapestry5/http/ContentType.java
@@ -15,6 +15,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -106,6 +107,12 @@
return baseType.equals(ct.baseType) && subType.equals(ct.subType) && parameters.equals(ct.parameters);
}
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(baseType, subType, parameters);
+ }
+
/**
* @return the base type of the content type
*/