diff --git a/src/main/java/org/carlspring/cloud/storage/s3fs/cache/S3FileAttributesCache.java b/src/main/java/org/carlspring/cloud/storage/s3fs/cache/S3FileAttributesCache.java index a0da7f86..7320f1d0 100644 --- a/src/main/java/org/carlspring/cloud/storage/s3fs/cache/S3FileAttributesCache.java +++ b/src/main/java/org/carlspring/cloud/storage/s3fs/cache/S3FileAttributesCache.java @@ -2,12 +2,15 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.stats.CacheStats; import org.carlspring.cloud.storage.s3fs.S3ObjectId; import org.carlspring.cloud.storage.s3fs.S3Path; import org.carlspring.cloud.storage.s3fs.attribute.S3BasicFileAttributes; import org.carlspring.cloud.storage.s3fs.attribute.S3PosixFileAttributes; import org.carlspring.cloud.storage.s3fs.util.S3Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.file.NoSuchFileException; import java.nio.file.attribute.BasicFileAttributes; @@ -20,6 +23,8 @@ public class S3FileAttributesCache { + private static final Logger logger = LoggerFactory.getLogger(S3FileAttributesCache.class); + private final S3Utils s3Utils = new S3Utils(); // This should be volatile, despite what IntelliJ / Sonar says. @@ -91,14 +96,18 @@ public static String generateCacheKey(S3ObjectId s3ObjectId, Class attrType) { String key = generateCacheKey(path, attrType); + logger.trace("Get cache for key {}", key); + Optional attrs = cache.getIfPresent(key); // Don't get confused - Caffeine returns `null` if the key does not exist. if(attrs == null) { + logger.trace("No cache found for key {}", key); // We need a way to preserve non-existing files/paths. // This is necessary, because the Files.exist() method is called multiple times from different threads // during checks. As a result multiple requests for the same path are executed within milliseconds. + logger.trace("Fetch data for key {}", key); attrs = Optional.ofNullable(fetchAttribute(path, key)); put(path, attrs); } @@ -138,11 +147,13 @@ public void put(final S3Path path, final Optional attrs) // To ensure this does not happen we always need to replace the BasicFileAttributes instances when // the PosixFileAttributes type is cached/updated. String basicKey = generateCacheKey(path, BasicFileAttributes.class); + logger.trace("Save response for key {}", basicKey); cache.put(basicKey, attrs); if(attrs.isPresent() && attrs.get() instanceof PosixFileAttributes) { String posixKey = generateCacheKey(path, PosixFileAttributes.class); + logger.trace("Save response for key {}", posixKey); cache.put(posixKey, attrs); } } @@ -155,6 +166,7 @@ public void put(final S3Path path, final Optional attrs) public void invalidate(final S3Path path, final Class attrType) { String key = generateCacheKey(path, attrType); + logger.trace("Invalidate cache key {}", key); cache.invalidate(key); } @@ -211,6 +223,7 @@ public void invalidate(final S3ObjectId objectId) { try { + logger.trace("Invalidate cache key {}", key); cache.invalidate(key); } catch (NullPointerException e) @@ -224,6 +237,7 @@ public void invalidate(final S3ObjectId objectId) public void invalidateAll() { + logger.trace("Invalidate all cache"); cache.invalidateAll(); } @@ -234,12 +248,21 @@ public CacheStats stats() protected Caffeine> cacheBuilder(int cacheTTL, int cacheSize) { - return Caffeine.newBuilder() - .expireAfter(new S3FileAttributesCachePolicy(cacheTTL)) - .maximumSize(cacheSize) - .softValues() - .recordStats() - ; + Caffeine> builder = Caffeine.newBuilder() + .expireAfter(new S3FileAttributesCachePolicy(cacheTTL)); + + if(cacheSize > 0) + { + builder.maximumSize(cacheSize); + } + + builder.recordStats(); + builder.evictionListener((String key, Optional value, RemovalCause cause) -> + logger.trace("Key {} was evicted (reason: {})", key, cause)); + builder.removalListener((String key, Optional value, RemovalCause cause) -> + logger.trace("Key {} was removed (reason: {})", key, cause)); + + return builder; } protected S3BasicFileAttributes fetchAttribute(S3Path path, String key)