content: 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;
      }
  }
  