NotFoundSliceLoaderDecorator.java
// Copyright (c) ZeroC, Inc.
package com.zeroc.Ice;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
/**
* Decorates SliceLoader to cache null results.
*/
final class NotFoundSliceLoaderDecorator implements SliceLoader {
private final SliceLoader _decoratee;
private final int _cacheSize;
private final AtomicReference<Logger> _logger;
private final Set<String> _notFoundSet = ConcurrentHashMap.newKeySet();
/**
* Creates a NotFoundSliceLoaderDecorator.
*
* @param decoratee The SliceLoader to decorate.
* @param cacheSize The maximum number of type IDs that can be cached.
* @param logger The logger used to warn when the cache is full. It's null when Ice.Warn.SliceLoader is set to 0.
*/
NotFoundSliceLoaderDecorator(SliceLoader decoratee, int cacheSize, Logger logger) {
_decoratee = decoratee;
_cacheSize = cacheSize;
_logger = new AtomicReference<>(logger);
}
@Override
public java.lang.Object newInstance(String typeId) {
if (_notFoundSet.contains(typeId)) {
return null;
}
java.lang.Object instance = _decoratee.newInstance(typeId);
if (instance == null) {
if (_notFoundSet.size() < _cacheSize) {
_notFoundSet.add(typeId);
} else {
Logger logger = _logger.getAndSet(null); // we warn at most once.
if (logger != null) {
logger.warning(
String.format(
"SliceLoader: Type ID '%s' not found and the not found cache is full. "
+ "The cache size is set to %d. You can increase the cache size by setting property "
+ "Ice.SliceLoader.NotFoundCacheSize.",
typeId, _cacheSize));
}
}
}
return instance;
}
}