javacaffeine

Size is not unloading from Caffeine caches


Right now i just wondering why, prob need help also.

So when i add values to my list it will be added but after 5 min it will remove, that works But if i do list.size() it still says 1 but there is no values inside


public class Test extends Runnable {

   private ExpiringSet<User> users; //User is just my object class 

   public Test() {
       users  = new ExpiringSet<User>(5, TimeUnit.MINUTES); //Sets the users

       users.add(new User("John"));
   }

   @Override
   public void run() {
       // This will always say 1 even after i wait 1hour ive seen it has increased after a while then it said 2 
       //and there is no values in the users
       System.out.println("Size: " + users.size()); 

       //But this is empty after 5min        
       for(Iterator<User> iter = users.iterator(); iter.hasNext(); ) {
           User user = (User)iter.next();
           System.out.println("User " + user.getName());
       }
   }

}

public class ExpiringSet<E> extends ForwardingSet<E> {
   private final Set<E> setView;

   public ExpiringSet(long duration, TimeUnit unit) {
       Cache<E, Boolean> cache = CaffeineFactory.newBuilder().expireAfterAccess(duration, unit).build();
       this.setView = Collections.newSetFromMap(cache.asMap());
   }

   @Override
   protected Set<E> delegate() {
       return this.setView;
   }
}

Basically i just want the users.size() to be 0 if there is no values inside users. It just seems weird when it says 1 and there is no values.


Solution

  • By default expired entries are removed lazily during routine maintenance, which is triggered by a few reads or a write. That results in size of the underlying map being exposed, whereas the entries will be hidden if queried for and evicted at some later point. The Cache.cleanUp() can be called to run the maintenance work.

    A background thread is required if you want expired entries to be removed promptly regardless of cache activity. This can be configured by configuring a Scheduler on the builder. Java 9+ includes a built-in JVM-wide scheduling thread rather than spinning up a new one, so the cache can be configured as,

    LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
        .scheduler(Scheduler.systemScheduler())
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build(key -> createExpensiveGraph(key));