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

commons.box.app.DataLoadingCache Maven / Gradle / Ivy

The newest version!
package commons.box.app;

import com.google.common.cache.*;

import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * 数据map 通过定义loader来实现值得载入机制
 * 

* 如果定义了max(值大于0时),此类将按需清除部分记录 * * @author xingxiuyi * 创建于 14/12/14 * 版权所有 xingxiuyi */ public final class DataLoadingCache { private final LoadingCache> cache; public static DataLoadingCache build() { DataCache.Spec spec = new DataCache.Spec(-1); return build(null, spec); } public static DataLoadingCache build(DataLoader loader) { DataCache.Spec spec = new DataCache.Spec(-1); return build(loader, spec); } public static DataLoadingCache build(DataLoader loader, long max) { DataCache.Spec spec = new DataCache.Spec(max); return build(loader, spec); } public static DataLoadingCache build(DataLoader loader, long max, long expireAfterAccess, long expireAfterWrite) { DataCache.Spec spec = new DataCache.Spec(max, expireAfterAccess, expireAfterWrite); return build(loader, spec); } public static DataLoadingCache build(DataLoader loader, long max, long expireAfterAccess, long expireAfterWrite, int initCapacity) { DataCache.Spec spec = new DataCache.Spec(max, expireAfterAccess, expireAfterWrite, initCapacity); return build(loader, spec); } public static DataLoadingCache build(DataLoader loader, long max, Consumer> removalCmd) { DataCache.Spec spec = new DataCache.Spec(max); return build(loader, spec, removalCmd); } public static DataLoadingCache build(DataLoader loader, long max, long expireAfterAccess, long expireAfterWrite, Consumer> removalCmd) { DataCache.Spec spec = new DataCache.Spec(max, expireAfterAccess, expireAfterWrite); return build(loader, spec, removalCmd); } public static DataLoadingCache build(DataLoader loader, long max, long expireAfterAccess, long expireAfterWrite, int initCapacity, Consumer> removalCmd) { DataCache.Spec spec = new DataCache.Spec(max, expireAfterAccess, expireAfterWrite, initCapacity); return build(loader, spec, removalCmd); } private static DataLoadingCache build(DataLoader loader, DataCache.Spec spec) { return build(loader, spec, null); } @SuppressWarnings("unchecked") private static DataLoadingCache build(DataLoader loader, DataCache.Spec spec, Consumer> removalCmd) { CacheBuilder> cb = (CacheBuilder) CacheBuilder.newBuilder(); if (spec != null) { if (spec.getMax() > 0) cb = cb.maximumSize(spec.getMax()); if (spec.getExpireAfterAccess() > 0) cb = cb.expireAfterAccess(spec.getExpireAfterAccess(), TimeUnit.MILLISECONDS); if (spec.getExpireAfterWrite() > 0) cb = cb.expireAfterWrite(spec.getExpireAfterWrite(), TimeUnit.MILLISECONDS); if (spec.getInitCapacity() > 0) cb = cb.initialCapacity(spec.getInitCapacity()); } if (removalCmd != null) cb = cb.removalListener(new RemovalCmds<>(removalCmd)); return new DataLoadingCache(cb.build(new DataCacheLoader<>(loader))); } private DataLoadingCache(LoadingCache> cache) { this.cache = cache; } public V get(K key) { try { DataEntry nv = this.cache.get(key); if (nv != null) return nv.getValue(); } catch (Throwable e) { throw new AppError("DataCache载入元素出错", e); } return null; } public V get(K key, DataLoader loader) { if (loader == null) return this.get(key); DataEntry nv = this.cache.getIfPresent(key); if (nv == null) { nv = new DataEntry<>(key, loader.load(key)); this.cache.put(key, nv); } return nv.getValue(); } public V getIfPresent(K key) { DataEntry nv = this.cache.getIfPresent(key); if (nv != null) return nv.getValue(); else return null; } public Map getAll(Iterable keys) { Map map = new HashMap<>(); try { Map> all = this.cache.getAll(keys); if (all != null) for (Map.Entry> me : all.entrySet()) { if (me == null || me.getKey() == null || me.getValue() == null) continue; map.put(me.getKey(), me.getValue().getValue()); } } catch (Throwable e) { throw new AppError("DataCache载入元素出错", e); } return map; } public void put(K key, V value) { if (key == null) return; this.cache.put(key, new DataEntry<>(key, value)); } public void putAll(Map map) { if (map == null) return; for (Map.Entry me : map.entrySet()) if (me != null) this.put(me.getKey(), me.getValue()); } public long size() { return this.cache.size(); } public void remove(K key) { this.cache.invalidate(key); } public void clear() { this.cache.cleanUp(); } public Map asMap() { Map map = new HashMap<>(); try { Map> all = this.cache.asMap(); if (all != null) for (Map.Entry> me : all.entrySet()) { if (me == null || me.getKey() == null || me.getValue() == null) continue; map.put(me.getKey(), me.getValue().getValue()); } } catch (Throwable e) { throw AppError.error("DataCache载入元素出错", e); } return map; } private static class DataCacheLoader extends CacheLoader> { private final DataLoader loader; public DataCacheLoader(DataLoader loader) { this.loader = (loader == null) ? new EmptyLoader() : loader;//保证loader不为空 } @SuppressWarnings("NullableProblems") @Override public DataEntry load(K key) throws Exception { return new DataEntry<>(key, this.loader.load(key)); } } private static class EmptyLoader implements DataLoader { @Override public V load(K key) { return null; } } private static class RemovalCmds implements RemovalListener> { private final Consumer> cmd; public RemovalCmds(Consumer> chain) { this.cmd = chain; } @Override public void onRemoval(@Nonnull RemovalNotification> notification) { if (notification.getValue() == null) return; if (this.cmd != null) this.cmd.accept(new DataEntry<>(notification.getKey(), notification.getValue().getValue())); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy