/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.cache.disk;
import javax.annotation.Nullable;
import java.io.File;
import android.content.Context;
import com.facebook.cache.common.CacheErrorLogger;
import com.facebook.cache.common.CacheEventListener;
import com.facebook.cache.common.NoOpCacheErrorLogger;
import com.facebook.cache.common.NoOpCacheEventListener;
import com.facebook.common.disk.DiskTrimmable;
import com.facebook.common.disk.DiskTrimmableRegistry;
import com.facebook.common.disk.NoOpDiskTrimmableRegistry;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.internal.Supplier;
import com.facebook.common.internal.Suppliers;
import com.facebook.common.util.ByteConstants;
/**
* Configuration class for a {@link DiskStorageCache}.
*/
public class DiskCacheConfig {
private final int mVersion;
private final String mBaseDirectoryName;
private final Supplier<File> mBaseDirectoryPathSupplier;
private final long mDefaultSizeLimit;
private final long mLowDiskSpaceSizeLimit;
private final long mMinimumSizeLimit;
private final EntryEvictionComparatorSupplier mEntryEvictionComparatorSupplier;
private final CacheErrorLogger mCacheErrorLogger;
private final CacheEventListener mCacheEventListener;
private final DiskTrimmableRegistry mDiskTrimmableRegistry;
private final Context mContext;
private final boolean mIndexPopulateAtStartupEnabled;
private DiskCacheConfig(Builder builder) {
mVersion = builder.mVersion;
mBaseDirectoryName = Preconditions.checkNotNull(builder.mBaseDirectoryName);
mBaseDirectoryPathSupplier = Preconditions.checkNotNull(builder.mBaseDirectoryPathSupplier);
mDefaultSizeLimit = builder.mMaxCacheSize;
mLowDiskSpaceSizeLimit = builder.mMaxCacheSizeOnLowDiskSpace;
mMinimumSizeLimit = builder.mMaxCacheSizeOnVeryLowDiskSpace;
mEntryEvictionComparatorSupplier =
Preconditions.checkNotNull(builder.mEntryEvictionComparatorSupplier);
mCacheErrorLogger =
builder.mCacheErrorLogger == null ?
NoOpCacheErrorLogger.getInstance() :
builder.mCacheErrorLogger;
mCacheEventListener =
builder.mCacheEventListener == null ?
NoOpCacheEventListener.getInstance() :
builder.mCacheEventListener;
mDiskTrimmableRegistry =
builder.mDiskTrimmableRegistry == null ?
NoOpDiskTrimmableRegistry.getInstance() :
builder.mDiskTrimmableRegistry;
mContext = builder.mContext;
mIndexPopulateAtStartupEnabled = builder.mIndexPopulateAtStartupEnabled;
}
public int getVersion() {
return mVersion;
}
public String getBaseDirectoryName() {
return mBaseDirectoryName;
}
public Supplier<File> getBaseDirectoryPathSupplier() {
return mBaseDirectoryPathSupplier;
}
public long getDefaultSizeLimit() {
return mDefaultSizeLimit;
}
public long getLowDiskSpaceSizeLimit() {
return mLowDiskSpaceSizeLimit;
}
public long getMinimumSizeLimit() {
return mMinimumSizeLimit;
}
public EntryEvictionComparatorSupplier getEntryEvictionComparatorSupplier() {
return mEntryEvictionComparatorSupplier;
}
public CacheErrorLogger getCacheErrorLogger() {
return mCacheErrorLogger;
}
public CacheEventListener getCacheEventListener() {
return mCacheEventListener;
}
public DiskTrimmableRegistry getDiskTrimmableRegistry() {
return mDiskTrimmableRegistry;
}
public Context getContext() {
return mContext;
}
public boolean getIndexPopulateAtStartupEnabled() {
return mIndexPopulateAtStartupEnabled;
}
/**
* Create a new builder.
*
* @param context If this is null, you must explicitly call
* {@link Builder#setBaseDirectoryPath(File)} or
* {@link Builder#setBaseDirectoryPathSupplier(Supplier)}
* or the config won't know where to physically locate the cache.
* @return
*/
public static Builder newBuilder(@Nullable Context context) {
return new Builder(context);
}
public static class Builder {
private int mVersion = 1;
private String mBaseDirectoryName = "image_cache";
private Supplier<File> mBaseDirectoryPathSupplier;
private long mMaxCacheSize = 40 * ByteConstants.MB;
private long mMaxCacheSizeOnLowDiskSpace = 10 * ByteConstants.MB;
private long mMaxCacheSizeOnVeryLowDiskSpace = 2 * ByteConstants.MB;
private EntryEvictionComparatorSupplier mEntryEvictionComparatorSupplier
= new DefaultEntryEvictionComparatorSupplier();
private CacheErrorLogger mCacheErrorLogger;
private CacheEventListener mCacheEventListener;
private DiskTrimmableRegistry mDiskTrimmableRegistry;
private boolean mIndexPopulateAtStartupEnabled;
private final @Nullable Context mContext;
private Builder(@Nullable Context context) {
mContext = context;
}
/**
* Sets the version.
*
* <p>The cache lives in a subdirectory identified by this version.
*/
public Builder setVersion(int version) {
mVersion = version;
return this;
}
/**
* Sets the name of the directory where the cache will be located.
*/
public Builder setBaseDirectoryName(String baseDirectoryName) {
mBaseDirectoryName = baseDirectoryName;
return this;
}
/**
* Sets the path to the base directory.
*
* <p>A directory with the given base directory name (see {@code setBaseDirectoryName}) will be
* appended to this path.
*/
public Builder setBaseDirectoryPath(final File baseDirectoryPath) {
mBaseDirectoryPathSupplier = Suppliers.of(baseDirectoryPath);
return this;
}
public Builder setBaseDirectoryPathSupplier(Supplier<File> baseDirectoryPathSupplier) {
mBaseDirectoryPathSupplier = baseDirectoryPathSupplier;
return this;
}
/**
* This is the default maximum size of the cache.
*/
public Builder setMaxCacheSize(long maxCacheSize) {
mMaxCacheSize = maxCacheSize;
return this;
}
/**
* This is the maximum size of the cache that is used when the device is low on disk space.
*
* See {@link DiskTrimmable#trimToMinimum()}.
*/
public Builder setMaxCacheSizeOnLowDiskSpace(long maxCacheSizeOnLowDiskSpace) {
mMaxCacheSizeOnLowDiskSpace = maxCacheSizeOnLowDiskSpace;
return this;
}
/**
* This is the maximum size of the cache when the device is extremely low on disk space.
*
* See {@link DiskTrimmable#trimToNothing()}.
*/
public Builder setMaxCacheSizeOnVeryLowDiskSpace(long maxCacheSizeOnVeryLowDiskSpace) {
mMaxCacheSizeOnVeryLowDiskSpace = maxCacheSizeOnVeryLowDiskSpace;
return this;
}
/**
* Provides the logic to determine the eviction order based on entry's access time and size
*/
public Builder setEntryEvictionComparatorSupplier(EntryEvictionComparatorSupplier supplier) {
mEntryEvictionComparatorSupplier = supplier;
return this;
}
/**
* The logger that is used to log errors made by the cache.
*/
public Builder setCacheErrorLogger(CacheErrorLogger cacheErrorLogger) {
mCacheErrorLogger = cacheErrorLogger;
return this;
}
/**
* The listener for cache events.
*/
public Builder setCacheEventListener(CacheEventListener cacheEventListener) {
mCacheEventListener = cacheEventListener;
return this;
}
/**
* The class that will contain a registry of caches to be trimmed in low disk space conditions.
*
* <p>See {@link DiskTrimmableRegistry}.
*/
public Builder setDiskTrimmableRegistry(DiskTrimmableRegistry diskTrimmableRegistry) {
mDiskTrimmableRegistry = diskTrimmableRegistry;
return this;
}
public Builder setIndexPopulateAtStartupEnabled(boolean indexEnabled) {
mIndexPopulateAtStartupEnabled = indexEnabled;
return this;
}
public DiskCacheConfig build() {
Preconditions.checkState(
mBaseDirectoryPathSupplier != null || mContext != null,
"Either a non-null context or a base directory path or supplier must be provided.");
if (mBaseDirectoryPathSupplier == null && mContext != null) {
mBaseDirectoryPathSupplier = new Supplier<File>() {
@Override
public File get() {
return mContext.getApplicationContext().getCacheDir();
}
};
}
return new DiskCacheConfig(this);
}
}
}