package com.airbnb.airpal.core.store.files;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.google.common.cache.Weigher;
import io.airlift.units.DataSize;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
@Slf4j
public class ExpiringFileStore
{
private LoadingCache<String, FileWithMetadata> fileWithMetadataCache;
private File basePath = new File(System.getProperty("java.io.tmpdir"));
public ExpiringFileStore(DataSize maxStorageSize)
{
long maxWeightInBytes = Math.round(Math.floor(maxStorageSize.getValue(DataSize.Unit.BYTE)));
this.fileWithMetadataCache = CacheBuilder.newBuilder().maximumWeight(maxWeightInBytes).weigher(new Weigher<String, FileWithMetadata>() {
@Override
public int weigh(String key, FileWithMetadata fileWithMetadata)
{
return (int) Math.round(fileWithMetadata.getSize().getValue(DataSize.Unit.BYTE));
}
}).removalListener(new RemovalListener<String, FileWithMetadata>() {
@Override
public void onRemoval(RemovalNotification<String, FileWithMetadata> notification)
{
File f = notification.getValue().getFile();
if (f != null && f.exists()) {
f.delete();
}
}
}).build(new CacheLoader<String, FileWithMetadata>() {
@Override
public FileWithMetadata load(String key)
throws Exception
{
File file = new File(basePath, key);
if (file.exists()) {
return new FileWithMetadata(file, new DataSize(file.length(), DataSize.Unit.BYTE), DateTime.now());
}
throw new FileNotFoundException();
}
});
}
public void addFile(String key, File file)
throws IOException
{
long fileSize = file.length();
fileWithMetadataCache.put(key, new FileWithMetadata(file, new DataSize(fileSize, DataSize.Unit.BYTE), DateTime.now()));
}
public File get(String key)
{
try {
return fileWithMetadataCache.get(key).getFile();
}
catch (ExecutionException e) {
return null;
}
}
@Value
private static class FileWithMetadata
{
private final File file;
private final DataSize size;
private final DateTime createdAt;
}
}