How should I implement the Guava cache when I plan to cache multiple values ​​efficiently?

I have a Java class with Guava LoadingCache<String, Integer>, and I plan to store two things in this cache: the average time of active employees was working for a day and efficiency. I cache these values ​​because it would be expensive to compute every time a request arrives. In addition, the contents of the cache will be updated ( refreshAfterWrite) every minute.

I was thinking of using CacheLoaderfor this situation, however its load method loads only one value per key. In mine, CacheLoaderI planned to do something like:

private Service service = new Service();

public Integer load(String key) throws Exception {
    if (key.equals("employeeAvg"))
        return calculateEmployeeAvg(service.getAllEmployees());

    if (key.equals("employeeEff"))
        return calculateEmployeeEff(service.getAllEmployees());

    return -1;
}

, service.getAllEmployees(), , , , CacheLoader .

LoadingCache.put(key, value), , service.getAllEmployees() " ". , LoadingCache.put(), refreshAfterWrite, .

?

+4
2

, (Effective Java Item 50). , , memoizing Supplier, .

public static class EmployeeStatistics {
  private final int average;
  private final int efficiency;
  // constructor, getters and setters
}

Supplier<EmployeeStatistics> statistics = Suppliers.memoize(
    new Supplier<EmployeeStatistics>() {
  @Override
  public EmployeeStatistics get() {
    List<Employee> employees = new Service().getAllEmployees();
    return new EmployeeStatistics(
        calculateEmployeeAvg(employees),
        calculateEmployeeEff(employees));
  }});

EmployeeStatistics .


Suppliers.memoize() Suppliers.memoizeWithExpiration(), , , Cache Supplier:

Supplier<EmployeeStatistics> statistics = new Supplier<EmployeeStatistics>() {
  private final Object key = new Object();
  private final LoadingCache<Object, EmployeeStatistics> cache =
      CacheBuilder.newBuilder()
        // configure your builder
        .build(
           new CacheLoader<Object, EmployeeStatistics>() {
             public EmployeeStatistics load(Object key) {
               // same behavior as the Supplier above
             }});

  @Override
  public EmployeeStatistics get() {
    return cache.get(key);
  }};
+3

, LoadingCache.put(), refreshAfterWrite, .

, load. , , , put . .

service.getAllEmployees , . calculateEmployeeAvg calculateEmployeeEff , . , , .

, , , . Pair- , . .


, ,

class EmployeeStatsCache {
    private long validUntil;
    private List<Employee> employeeList;
    private Integer employeeAvg;
    private Integer employeeEff;

    private boolean isValid() {
        return System.currentTimeMillis() <= validUntil;
    }

    private synchronized List<Employee> getEmployeeList() {
        if (!isValid || employeeList==null) {
            employeeList = service.getAllEmployees();
            validUntil = System.currentTimeMillis() + VALIDITY_MILLIS;
        }
        return employeeList;
    }

    public synchronized int getEmployeeAvg() {
        if (!isValid || employeeAvg==null) {
             employeeAvg = calculateEmployeeAvg(getEmployeeList());
        }
        return employeeAvg;
    }

    public synchronized int getEmployeeEff() {
        if (!isValid || employeeAvg==null) {
             employeeAvg = calculateEmployeeEff(getEmployeeList());
        }
        return employeeAvg;
    }
}

synchronized, . (, Atomic*), , , , Guava Cache.


, Suppliers#memoizeWithExpiration . , .

+2

Source: https://habr.com/ru/post/1599192/


All Articles