下面列出了com.google.common.cache.CacheBuilder#recordStats ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Creates a solver for the given problem, constructing caches with the
* given {@link CacheBuilder}. The solver must then be started by calling
* {@link #solve()}.
* @param tabulationProblem The tabulation problem to solve
* @param flowFunctionCacheBuilder A valid {@link CacheBuilder} or
* <code>null</code> if no caching is to be used for flow functions.
*/
public IFDSSolver(IFDSTabulationProblem<N,D,M,I> tabulationProblem,
@SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder) {
if(logger.isDebugEnabled())
flowFunctionCacheBuilder = flowFunctionCacheBuilder.recordStats();
this.zeroValue = tabulationProblem.zeroValue();
this.icfg = tabulationProblem.interproceduralCFG();
FlowFunctions<N, D, M> flowFunctions = tabulationProblem.autoAddZero() ?
new ZeroedFlowFunctions<N,D,M>(tabulationProblem.flowFunctions(), zeroValue) : tabulationProblem.flowFunctions();
if(flowFunctionCacheBuilder!=null) {
ffCache = new FlowFunctionCache<N,D,M>(flowFunctions, flowFunctionCacheBuilder);
flowFunctions = ffCache;
} else {
ffCache = null;
}
this.flowFunctions = flowFunctions;
this.initialSeeds = tabulationProblem.initialSeeds();
this.jumpFn = new JumpFunctions<N,D>();
this.followReturnsPastSeeds = tabulationProblem.followReturnsPastSeeds();
this.numThreads = Math.max(1,tabulationProblem.numThreads());
this.executor = getExecutor();
}
public ForceTarget(
ForceTargetConfigBean conf, boolean useCompression, boolean showTrace
) {
this.conf = conf;
this.useCompression = useCompression;
this.showTrace = showTrace;
CacheBuilder cacheBuilder = CacheBuilder.newBuilder()
.maximumSize(500)
.expireAfterAccess(1, TimeUnit.HOURS);
if(LOG.isDebugEnabled()) {
cacheBuilder.recordStats();
}
forceWriters = cacheBuilder.build(new ForceWriterLoader());
cacheCleaner = new CacheCleaner(forceWriters, "ForceTarget", 10 * 60 * 1000);
}
/**
* Builds a new empty cache.
*/
private void buildCache(final boolean recordStats) {
// Setting concurrency level to 1 ensures global LRU eviction
// by limiting all entries to one segment
// (see http://stackoverflow.com/questions/10236057/guava-cache-eviction-policy ).
// The "penalty" for this appears to be serialized put of the object
// AFTER it has been loaded - which should not be a problem.
final CacheBuilder<CanvasId, CachedCanvasData> cacheBuilder =
CacheBuilder.newBuilder()
.concurrencyLevel(1)
.maximumWeight(getKilobyteCapacity())
.weigher(weigher)
.removalListener(asyncRemovalListener);
if (recordStats) {
cacheBuilder.recordStats();
}
this.canvasIdToDataCache = cacheBuilder.build(canvasDataLoader);
}
public LocalAsyncCache(final int maximumSize, final int ttl, final TimeUnit unit, final MetricFactory metricFactory, final String cacheName) {
this.loader = null;
this.loadingCache = null;
this.failOnMissingEntries = true; // fake value, not in use.
this.cacheName = cacheName;
final boolean collectStats = metricFactory != null;
final CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
.maximumSize(maximumSize)
.expireAfterWrite(ttl, unit);
if (collectStats) {
builder.recordStats();
}
this.localCache = builder.build();
if (collectStats) {
GuavaCacheGaugesFactory.createGauges(metricFactory, localCache, "LocalAsyncCache-" + cacheName);
}
}
private LoadingCache<Long, byte[]> initCache(long maximumNumberOfCacheBlocks, java.time.Duration timeToLive) {
CacheBuilder<Object, Object> cb =
CacheBuilder.newBuilder().maximumSize(maximumNumberOfCacheBlocks).expireAfterWrite(timeToLive);
if (debugAccess) {
cb.recordStats();
}
return cb.build(new CacheLoader<Long, byte[]>() {
public byte[] load(@Nonnull Long key) throws IOException {
return readRemoteCacheSizedChunk(key);
}
});
}
public CacheBuilder cacheBuilder() {
CacheBuilder builder = CacheBuilder.newBuilder();
if(cacheConcurrencyLevel >= 0) { builder.concurrencyLevel(cacheConcurrencyLevel); }
if(cacheExpireAfterAccessMs >= 0) { builder.expireAfterAccess(cacheExpireAfterAccessMs, TimeUnit.MILLISECONDS); }
if(cacheExpireAfterWriteMs >= 0) { builder.expireAfterWrite(cacheExpireAfterWriteMs, TimeUnit.MILLISECONDS); }
if(cacheInitialCapacity >= 0) { builder.initialCapacity(cacheInitialCapacity); }
if(cacheMaximumSize >= 0) { builder.maximumSize(cacheMaximumSize); }
if(cacheRefreshAfterWriteMs >= 0) { builder.refreshAfterWrite(cacheRefreshAfterWriteMs, TimeUnit.MILLISECONDS); }
if(cacheRecordStats) { builder.recordStats(); }
return builder;
}
/**
* Creates a solver for the given problem, constructing caches with the given {@link CacheBuilder}. The solver must then be started by calling
* {@link #solve()}.
* @param flowFunctionCacheBuilder A valid {@link CacheBuilder} or <code>null</code> if no caching is to be used for flow functions.
* @param edgeFunctionCacheBuilder A valid {@link CacheBuilder} or <code>null</code> if no caching is to be used for edge functions.
*/
public IDESolver(IDETabulationProblem<N,D,M,V,I> tabulationProblem, @SuppressWarnings("rawtypes") CacheBuilder flowFunctionCacheBuilder, @SuppressWarnings("rawtypes") CacheBuilder edgeFunctionCacheBuilder) {
if(logger.isDebugEnabled()) {
if(flowFunctionCacheBuilder != null)
flowFunctionCacheBuilder = flowFunctionCacheBuilder.recordStats();
if(edgeFunctionCacheBuilder != null)
edgeFunctionCacheBuilder = edgeFunctionCacheBuilder.recordStats();
}
this.zeroValue = tabulationProblem.zeroValue();
this.icfg = tabulationProblem.interproceduralCFG();
FlowFunctions<N, D, M> flowFunctions = tabulationProblem.autoAddZero() ?
new ZeroedFlowFunctions<N,D,M>(tabulationProblem.flowFunctions(), tabulationProblem.zeroValue()) : tabulationProblem.flowFunctions();
EdgeFunctions<N, D, M, V> edgeFunctions = tabulationProblem.edgeFunctions();
if(flowFunctionCacheBuilder!=null) {
ffCache = new FlowFunctionCache<N,D,M>(flowFunctions, flowFunctionCacheBuilder);
flowFunctions = ffCache;
} else {
ffCache = null;
}
if(edgeFunctionCacheBuilder!=null) {
efCache = new EdgeFunctionCache<N,D,M,V>(edgeFunctions, edgeFunctionCacheBuilder);
edgeFunctions = efCache;
} else {
efCache = null;
}
this.flowFunctions = flowFunctions;
this.edgeFunctions = edgeFunctions;
this.initialSeeds = tabulationProblem.initialSeeds();
this.unbalancedRetSites = Collections.newSetFromMap(new ConcurrentHashMap<N, Boolean>());
this.valueLattice = tabulationProblem.joinLattice();
this.allTop = tabulationProblem.allTopFunction();
this.jumpFn = new JumpFunctions<N,D,V>(allTop);
this.followReturnsPastSeeds = tabulationProblem.followReturnsPastSeeds();
this.numThreads = Math.max(1,tabulationProblem.numThreads());
this.computeValues = tabulationProblem.computeValues();
this.executor = getExecutor();
}
MapCache(final String name, final CacheConfiguration config) {
this.name = name;
CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
if (config.isStatisticsEnabled()) {
cacheBuilder.recordStats();
}
if (config.isSoftValuesEnabled()) {
cacheBuilder.softValues();
}
if (config.getInitialCapacity() >= 0) {
cacheBuilder.initialCapacity(config.getInitialCapacity());
}
if (config.getMaximumSize() >= 0) {
if (config.isArraySizeEnabled()) {
cacheBuilder.maximumWeight(config.getMaximumSize());
cacheBuilder.weigher(new Weigher<K, V>() {
@Override
public int weigh(final K key, final V value) {
if (value instanceof byte[]) {
return ((byte[]) value).length;
}
throw new IllegalStateException("Using array size is only supported for byte arrays"); //$NON-NLS-1$
}
});
} else {
cacheBuilder.maximumSize(config.getMaximumSize());
}
}
backend = cacheBuilder.build();
}
@SuppressWarnings("unchecked")
private Cache<String, Optional<List<Map<String, Field>>>> buildCache() {
CacheBuilder cacheBuilder = CacheBuilder.newBuilder();
if (!conf.cacheConfig.enabled) {
return (conf.lookupMode == QUERY)
? cacheBuilder.build(conf.useBulkAPI ? new ForceLookupBulkLoader(this) : new ForceLookupSoapLoader(this))
: cacheBuilder.maximumSize(0).build();
}
if (conf.cacheConfig.maxSize == -1) {
conf.cacheConfig.maxSize = Long.MAX_VALUE;
}
if(LOG.isDebugEnabled()) {
cacheBuilder.recordStats();
}
// CacheBuilder doesn't support specifying type thus suffers from erasure, so
// we build it with this if / else logic.
if (conf.cacheConfig.evictionPolicyType == EvictionPolicyType.EXPIRE_AFTER_ACCESS) {
cacheBuilder.maximumSize(conf.cacheConfig.maxSize).expireAfterAccess(conf.cacheConfig.expirationTime, conf.cacheConfig.timeUnit);
} else if (conf.cacheConfig.evictionPolicyType == EvictionPolicyType.EXPIRE_AFTER_WRITE) {
cacheBuilder.maximumSize(conf.cacheConfig.maxSize).expireAfterWrite(conf.cacheConfig.expirationTime, conf.cacheConfig.timeUnit);
} else {
throw new IllegalArgumentException(Utils.format("Unrecognized EvictionPolicyType: '{}'",
conf.cacheConfig.evictionPolicyType
));
}
return (conf.lookupMode == QUERY)
? cacheBuilder.build(conf.useBulkAPI ? new ForceLookupBulkLoader(this) : new ForceLookupSoapLoader(this))
: cacheBuilder.build();
}
public RateLimiter(int maximumSize, boolean recordStats) {
CacheBuilder<Object, Object> cache = CacheBuilder.newBuilder()
.expireAfterWrite(1, DAYS);
if (maximumSize != NO_MAXIMUM_SIZE) {
cache.maximumSize(maximumSize);
}
if (recordStats) {
cache.recordStats();
}
acquiredRecently = cache.build();
}
public LocalAsyncCache(final int maximumSize, final int ttl, final TimeUnit unit, final CacheLoader<K, V> loader,
final MetricFactory metricFactory, final String cacheName, final boolean failOnMissingEntries) {
this.loader = loader;
this.cacheName = cacheName;
this.failOnMissingEntries = failOnMissingEntries;
final boolean collectStats = metricFactory != null;
final CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
.maximumSize(maximumSize)
.expireAfterWrite(ttl, unit);
if (collectStats)
builder.recordStats();
this.loadingCache = builder
.build(new com.google.common.cache.CacheLoader<K, ComposableFuture<V>>() {
public ComposableFuture<V> load(final K key) throws Exception {
return loadElement(key);
}
@Override
public Map<K, ComposableFuture<V>> loadAll(final Iterable<? extends K> keys) throws Exception {
return loadElements(Lists.newArrayList(keys));
}
});
if (collectStats) {
GuavaCacheGaugesFactory.createGauges(metricFactory, loadingCache, "LocalAsyncCache-" + cacheName);
}
this.localCache = null;
}
public void init(String baseDir) throws IOException {
this.baseDir = convertToAbsolutePath(baseDir);
final GlobalDictStore globalDictStore = new GlobalDictHDFSStore(this.baseDir);
Long[] versions = globalDictStore.listAllVersions();
if (versions.length == 0) {
this.metadata = new GlobalDictMetadata(0, 0, 0, 0, null, new TreeMap<AppendDictSliceKey, String>());
return; // for the removed SegmentAppendTrieDictBuilder
}
final long latestVersion = versions[versions.length - 1];
final Path latestVersionPath = globalDictStore.getVersionDir(latestVersion);
this.metadata = globalDictStore.getMetadata(latestVersion);
this.bytesConvert = metadata.bytesConverter;
// see: https://github.com/google/guava/wiki/CachesExplained
this.evictionThreshold = KylinConfig.getInstanceFromEnv().getDictionarySliceEvicationThreshold();
int cacheMaximumSize = KylinConfig.getInstanceFromEnv().getCachedDictMaxSize();
CacheBuilder cacheBuilder = CacheBuilder.newBuilder().softValues();
// To be compatible with Guava 11
boolean methodExists = methodExistsInClass(CacheBuilder.class, "recordStats");
if (methodExists) {
cacheBuilder = cacheBuilder.recordStats();
}
if (cacheMaximumSize > 0) {
cacheBuilder = cacheBuilder.maximumSize(cacheMaximumSize);
logger.info("Set dict cache maximum size to " + cacheMaximumSize);
}
this.dictCache = cacheBuilder
.removalListener(new RemovalListener<AppendDictSliceKey, AppendDictSlice>() {
@Override
public void onRemoval(RemovalNotification<AppendDictSliceKey, AppendDictSlice> notification) {
logger.info("Evict slice with key {} and value {} caused by {}, size {}/{}",
notification.getKey(), notification.getValue(), notification.getCause(),
dictCache.size(), metadata.sliceFileMap.size());
}
}).build(new CacheLoader<AppendDictSliceKey, AppendDictSlice>() {
@Override
public AppendDictSlice load(AppendDictSliceKey key) throws Exception {
AppendDictSlice slice = globalDictStore.readSlice(latestVersionPath.toString(),
metadata.sliceFileMap.get(key));
logger.trace("Load slice with key {} and value {}", key, slice);
return slice;
}
});
}
/**
*
* @param concurrencyLevel
* @param timeToLiveSeconds 设置写缓存后过期时间(单位:秒)
* @param timeToIdleSeconds 设置读缓存后过期时间(单位:秒)
* @param initialCapacity
* @param maximumSize
* @param recordStats
* @param removalListener
* @return
*/
public static <K, V> LoadingCache<K, V> createLoadingCache(Integer concurrencyLevel, Long timeToLiveSeconds, Long timeToIdleSeconds, Integer initialCapacity,
Integer maximumSize, boolean recordStats, RemovalListener<K, V> removalListener) {
if (removalListener == null) {
removalListener = new RemovalListener<K, V>() {
@Override
public void onRemoval(RemovalNotification<K, V> notification) {
log.info(notification.getKey() + " was removed");
}
};
}
CacheBuilder<K, V> cacheBuilder = CacheBuilder.newBuilder().removalListener(removalListener);
//设置并发级别为8,并发级别是指可以同时写缓存的线程数
cacheBuilder.concurrencyLevel(concurrencyLevel);
if (timeToLiveSeconds != null && timeToLiveSeconds > 0) {
//设置写缓存后8秒钟过期
cacheBuilder.expireAfterWrite(timeToLiveSeconds, TimeUnit.SECONDS);
}
if (timeToIdleSeconds != null && timeToIdleSeconds > 0) {
//设置访问缓存后8秒钟过期
cacheBuilder.expireAfterAccess(timeToIdleSeconds, TimeUnit.SECONDS);
}
//设置缓存容器的初始容量为10
cacheBuilder.initialCapacity(initialCapacity);
//设置缓存最大容量为100,超过100之后就会按照LRU最近最少使用算法来移除缓存项
cacheBuilder.maximumSize(maximumSize);
if (recordStats) {
//设置要统计缓存的命中率
cacheBuilder.recordStats();
}
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
LoadingCache<K, V> loadingCache = cacheBuilder.build(new CacheLoader<K, V>() {
@Override
public V load(K key) throws Exception {
return null;
}
});
return loadingCache;
// for (int i = 0; i < 20; i++)
// {
// //从缓存中得到数据,由于我们没有设置过缓存,所以需要通过CacheLoader加载缓存数据
// Long student = studentCache.get("p");
// System.out.println(student);
// //休眠1秒
// TimeUnit.SECONDS.sleep(1);
// }
// System.out.println("cache stats:");
//最后打印缓存的命中率等 情况
// System.out.println(studentCache.stats().toString());
}
public JdbcTeeProcessor(
String schema,
String tableNameTemplate,
List<JdbcFieldColumnParamMapping> customMappings,
List<JdbcFieldColumnMapping> generatedColumnMappings,
boolean caseSensitive,
boolean rollbackOnError,
boolean useMultiRowOp,
int maxPrepStmtParameters,
ChangeLogFormat changeLogFormat,
HikariPoolConfigBean hikariConfigBean,
JDBCOperationType defaultOp,
UnsupportedOperationAction unsupportedAction
) {
this.jdbcUtil = UtilsProvider.getJdbcUtil();
this.schema = schema;
this.tableNameTemplate = tableNameTemplate;
this.customMappings = customMappings;
this.generatedColumnMappings = generatedColumnMappings;
this.caseSensitive = caseSensitive;
this.rollbackOnError = rollbackOnError;
this.useMultiRowOp = useMultiRowOp;
this.maxPrepStmtParameters = maxPrepStmtParameters;
this.changeLogFormat = changeLogFormat;
this.hikariConfigBean = hikariConfigBean;
this.defaultOperation = defaultOp;
this.unsupportedAction = unsupportedAction;
this.dynamicTableName = this.jdbcUtil.isElString(tableNameTemplate);
CacheBuilder cacheBuilder = CacheBuilder.newBuilder()
.maximumSize(500)
.expireAfterAccess(1, TimeUnit.HOURS);
if(LOG.isDebugEnabled()) {
cacheBuilder.recordStats();
}
this.recordWriters = cacheBuilder.build(new RecordWriterLoader());
cacheCleaner = new CacheCleaner(this.recordWriters, "JdbcTeeProcessor", 10 * 60 * 1000);
}
public JdbcTarget(
final String schemaNameTemplate,
final String tableNameTemplate,
final List<JdbcFieldColumnParamMapping> customMappings,
final boolean caseSensitive,
final boolean rollbackOnError,
final boolean useMultiRowOp,
int maxPrepStmtParameters,
final ChangeLogFormat changeLogFormat,
final int defaultOpCode,
UnsupportedOperationAction unsupportedAction,
DuplicateKeyAction duplicateKeyAction,
HikariPoolConfigBean hikariConfigBean,
final List<String> customDataSqlStateCodes
) {
this.jdbcUtil = UtilsProvider.getJdbcUtil();
this.schemaNameTemplate = schemaNameTemplate;
this.tableNameTemplate = tableNameTemplate;
this.customMappings = customMappings;
this.caseSensitive = caseSensitive;
this.rollbackOnError = rollbackOnError;
this.useMultiRowOp = useMultiRowOp;
this.maxPrepStmtParameters = maxPrepStmtParameters;
this.changeLogFormat = changeLogFormat;
this.defaultOpCode = defaultOpCode;
this.unsupportedAction = unsupportedAction;
this.duplicateKeyAction = duplicateKeyAction;
this.hikariConfigBean = hikariConfigBean;
this.dynamicTableName = jdbcUtil.isElString(tableNameTemplate);
this.dynamicSchemaName = jdbcUtil.isElString(schemaNameTemplate);
this.customDataSqlStateCodes = customDataSqlStateCodes;
this.tableAutoCreate = false;
CacheBuilder cacheBuilder = CacheBuilder.newBuilder()
.maximumSize(500)
.expireAfterAccess(1, TimeUnit.HOURS)
.removalListener((RemovalListener<SchemaAndTable, JdbcRecordWriter>) removal -> {
removal.getValue().deinit();
});
if(LOG.isDebugEnabled()) {
cacheBuilder.recordStats();
}
this.recordWriters = cacheBuilder.build(new RecordWriterLoader());
cacheCleaner = new CacheCleaner(this.recordWriters, "JdbcTarget", 10 * 60 * 1000);
}
@Override
@SuppressWarnings("unchecked")
protected List<ConfigIssue> init() {
List<ConfigIssue> issues = super.init();
if (recordCountWindow <= 0) {
issues.add(getContext().createConfigIssue(Groups.DE_DUP.name(), "recordCountWindow", Errors.DEDUP_00,
recordCountWindow));
}
if (timeWindowSecs < 0) {
issues.add(getContext().createConfigIssue(Groups.DE_DUP.name(), "timeWindowSecs", Errors.DEDUP_01,
timeWindowSecs));
}
if (compareFields == SelectFields.SPECIFIED_FIELDS && fieldsToCompare.isEmpty()) {
issues.add(getContext().createConfigIssue(Groups.DE_DUP.name(), "compareFields", Errors.DEDUP_02));
}
if (issues.isEmpty()) {
hasher = HashingUtil.getHasher(HashingUtil.HashType.MURMUR3_128);
funnel = (compareFields == SelectFields.ALL_FIELDS) ? HashingUtil.getRecordFunnel(
Collections.EMPTY_LIST,
false,
true,
'\u0000'
) : HashingUtil.getRecordFunnel(fieldsToCompare, false, true, '\u0000');
Map<String, Object> runnerSharedMap = getContext().getStageRunnerSharedMap();
synchronized (runnerSharedMap) {
if(!runnerSharedMap.containsKey(CACHE_KEY)) {
CacheBuilder cacheBuilder = CacheBuilder.newBuilder();
if (timeWindowSecs > 0) {
cacheBuilder.expireAfterWrite(timeWindowSecs, TimeUnit.SECONDS);
}
if(LOG.isDebugEnabled()) {
cacheBuilder.recordStats();
}
hashCache = cacheBuilder.build();
runnerSharedMap.put(CACHE_KEY, hashCache);
} else {
hashCache = (Cache<HashCode, HashCode>) runnerSharedMap.get(CACHE_KEY);
}
}
cacheCleaner = new CacheCleaner(hashCache, "DeDupProcessor", 10 * 60 * 1000);
hashBuffer = XEvictingQueue.create(recordCountWindow);
hashAttrName = getInfo() + ".hash";
uniqueLane = getContext().getOutputLanes().get(OutputStreams.UNIQUE.ordinal());
duplicateLane = getContext().getOutputLanes().get(OutputStreams.DUPLICATE.ordinal());
}
return issues;
}
public void init(String baseDir) throws IOException {
this.baseDir = convertToAbsolutePath(baseDir);
final GlobalDictStore globalDictStore = new GlobalDictHDFSStore(this.baseDir);
Long[] versions = globalDictStore.listAllVersions();
if (versions.length == 0) {
this.metadata = new GlobalDictMetadata(0, 0, 0, 0, null, new TreeMap<AppendDictSliceKey, String>());
return; // for the removed SegmentAppendTrieDictBuilder
}
final long latestVersion = versions[versions.length - 1];
final Path latestVersionPath = globalDictStore.getVersionDir(latestVersion);
this.metadata = globalDictStore.getMetadata(latestVersion);
this.bytesConvert = metadata.bytesConverter;
// see: https://github.com/google/guava/wiki/CachesExplained
this.evictionThreshold = KylinConfig.getInstanceFromEnv().getDictionarySliceEvicationThreshold();
int cacheMaximumSize = KylinConfig.getInstanceFromEnv().getCachedDictMaxSize();
CacheBuilder cacheBuilder = CacheBuilder.newBuilder().softValues();
// To be compatible with Guava 11
boolean methodExists = methodExistsInClass(CacheBuilder.class, "recordStats");
if (methodExists) {
cacheBuilder = cacheBuilder.recordStats();
}
if (cacheMaximumSize > 0) {
cacheBuilder = cacheBuilder.maximumSize(cacheMaximumSize);
logger.info("Set dict cache maximum size to " + cacheMaximumSize);
}
this.dictCache = cacheBuilder
.removalListener(new RemovalListener<AppendDictSliceKey, AppendDictSlice>() {
@Override
public void onRemoval(RemovalNotification<AppendDictSliceKey, AppendDictSlice> notification) {
logger.info("Evict slice with key {} and value {} caused by {}, size {}/{}",
notification.getKey(), notification.getValue(), notification.getCause(),
dictCache.size(), metadata.sliceFileMap.size());
}
}).build(new CacheLoader<AppendDictSliceKey, AppendDictSlice>() {
@Override
public AppendDictSlice load(AppendDictSliceKey key) throws Exception {
AppendDictSlice slice = globalDictStore.readSlice(latestVersionPath.toString(),
metadata.sliceFileMap.get(key));
logger.trace("Load slice with key {} and value {}", key, slice);
return slice;
}
});
}