* {@inheritDoc}
*/
public boolean putEntryIfAbsent(Entry entry, Backend backend, long entryID)
{
// Create the cache entry based on the provided information.
CacheEntry cacheEntry = new CacheEntry(entry, backend, entryID);
// Obtain a lock on the cache. If this fails, then don't do anything.
try
{
if (!cacheWriteLock.tryLock(getLockTimeout(), TimeUnit.MILLISECONDS))
{
// We can't rule out the possibility of a conflict, so return false.
return false;
}
}
catch (Exception e)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
// We can't rule out the possibility of a conflict, so return false.
return false;
}
// At this point, we hold the lock. No matter what, we must release the
// lock before leaving this method, so do that in a finally block.
try
{
// See if the entry already exists in the cache. If it does, then we will
// fail and not actually store the entry.
if (dnMap.containsKey(entry.getDN()))
{
return false;
}
// See if the current memory usage is within acceptable constraints. If
// so, then add the entry to the cache (or replace it if it is already
// present). If not, then remove an existing entry and don't add the new
// entry.
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
if (usedMemory > maxAllowedMemory)
{
Iterator<CacheEntry> iterator = dnMap.values().iterator();
if (iterator.hasNext())
{
CacheEntry ce = iterator.next();
iterator.remove();
HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend());
if (m != null)
{
m.remove(ce.getEntryID());
}
}
}
else
{
// Add the entry to the cache. This will replace it if it is already
// present and add it if it isn't.
dnMap.put(entry.getDN(), cacheEntry);
HashMap<Long,CacheEntry> map = idMap.get(backend);
if (map == null)
{
map = new HashMap<Long,CacheEntry>();
map.put(entryID, cacheEntry);
idMap.put(backend, map);
}
else
{
map.put(entryID, cacheEntry);
}
// See if a cap has been placed on the maximum number of entries in the
// cache. If so, then see if we have exceeded it and we need to purge
// entries until we're within the limit.
int entryCount = dnMap.size();
if ((maxEntries > 0) && (entryCount > maxEntries))
{
Iterator<CacheEntry> iterator = dnMap.values().iterator();
while (iterator.hasNext() && (entryCount > maxEntries))
{
CacheEntry ce = iterator.next();
iterator.remove();
HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend());
if (m != null)
{
m.remove(ce.getEntryID());
}
entryCount--;
}
}