All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.hana.datalake.files.util.LRUCache Maven / Gradle / Ivy

package com.sap.hana.datalake.files.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Predicate;

public class LRUCache {

  private static final Logger LOG = LoggerFactory.getLogger(LRUCache.class);

  private final Map internalCache;
  private final Predicate validator;

  public LRUCache(final int maxItems) {
    this(maxItems, item -> true);
  }

  public LRUCache(final int maxItems, final Predicate validator) {
    if (maxItems < 1) {
      throw new IllegalArgumentException("Cache cannot contain less than 1 entry");
    }

    if (validator == null) {
      throw new IllegalArgumentException("Validator cannot be null");
    }

    this.validator = validator;
    this.internalCache = new LinkedHashMap(maxItems + 1, 0.75f, true) {
      @Override
      protected boolean removeEldestEntry(final Map.Entry eldest) {
        final boolean shouldRemoveEldest = this.size() > maxItems;

        if (shouldRemoveEldest && LOG.isDebugEnabled()) {
          LOG.debug("Evicting least recently used entry: {}", eldest.getKey());
        }

        return shouldRemoveEldest;
      }
    };
  }

  public synchronized int size() {
    return this.internalCache.size();
  }

  public synchronized boolean has(final K key) {
    return this.get(key) != null;
  }

  public synchronized V get(final K key) {
    LOG.debug("Retrieving entry: {}", key);

    final V value = this.internalCache.get(key);

    if (value != null && !this.validator.test(value)) {
      LOG.debug("Purging invalid entry: {}", key);
      this.remove(key);
      return null;
    }

    return value;
  }

  public synchronized V put(final K key, final V value) {
    LOG.debug("Updating entry: {}", key);
    return this.internalCache.put(key, value);
  }

  public synchronized V putIfAbsent(final K key, final V value) {
    final V currentValue = this.get(key);

    if (currentValue != null) {
      return currentValue;
    }

    return this.put(key, value);
  }

  public synchronized V remove(final K key) {
    LOG.debug("Removing entry: {}", key);
    return this.internalCache.remove(key);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy