| | |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.concurrent.locks.Lock; |
| | | import java.util.concurrent.locks.ReadWriteLock; |
| | | import java.util.concurrent.locks.ReentrantReadWriteLock; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | |
| | | private static final Runtime runtime = Runtime.getRuntime(); |
| | | |
| | | /** The mapping between entry backends/IDs and entries. */ |
| | | private HashMap<Backend<?>, HashMap<Long, CacheEntry>> idMap; |
| | | private Map<Backend<?>, Map<Long, CacheEntry>> idMap; |
| | | |
| | | /** The mapping between DNs and entries. */ |
| | | private LinkedHashMap<DN,CacheEntry> dnMap; |
| | |
| | | * The lock used to provide threadsafe access when changing the contents of |
| | | * the cache. |
| | | */ |
| | | private ReentrantReadWriteLock cacheLock; |
| | | private ReadWriteLock cacheLock; |
| | | private Lock cacheWriteLock; |
| | | private Lock cacheReadLock; |
| | | |
| | |
| | | configuration.addFIFOChangeListener (this); |
| | | |
| | | // Initialize the cache structures. |
| | | idMap = new HashMap<Backend<?>, HashMap<Long, CacheEntry>>(); |
| | | dnMap = new LinkedHashMap<DN,CacheEntry>(); |
| | | idMap = new HashMap<>(); |
| | | dnMap = new LinkedHashMap<>(); |
| | | |
| | | // Initialize locks. |
| | | cacheLock = new ReentrantReadWriteLock(true); |
| | |
| | | |
| | | // Read configuration and apply changes. |
| | | boolean applyChanges = true; |
| | | ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>(); |
| | | List<LocalizableMessage> errorMessages = new ArrayList<>(); |
| | | EntryCacheCommon.ConfigErrorHandler errorHandler = |
| | | EntryCacheCommon.getConfigErrorHandler ( |
| | | EntryCacheCommon.ConfigPhase.PHASE_INIT, null, errorMessages |
| | |
| | | // Indicate cache miss. |
| | | cacheMisses.getAndIncrement(); |
| | | return null; |
| | | } else { |
| | | // Indicate cache hit. |
| | | cacheHits.getAndIncrement(); |
| | | return e.getEntry(); |
| | | } |
| | | // Indicate cache hit. |
| | | cacheHits.getAndIncrement(); |
| | | return e.getEntry(); |
| | | } finally { |
| | | cacheReadLock.unlock(); |
| | | } |
| | |
| | | // Locate specific backend map and return the entry DN by ID. |
| | | cacheReadLock.lock(); |
| | | try { |
| | | HashMap<Long, CacheEntry> backendMap = idMap.get(backend); |
| | | Map<Long, CacheEntry> backendMap = idMap.get(backend); |
| | | if (backendMap != null) { |
| | | CacheEntry e = backendMap.get(entryID); |
| | | if (e != null) { |
| | |
| | | CacheEntry ce = iterator.next(); |
| | | iterator.remove(); |
| | | |
| | | HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | Map<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | if (m != null) |
| | | { |
| | | m.remove(ce.getEntryID()); |
| | |
| | | // present and add it if it isn't. |
| | | dnMap.put(entry.getName(), cacheEntry); |
| | | |
| | | HashMap<Long,CacheEntry> map = idMap.get(backend); |
| | | Map<Long,CacheEntry> map = idMap.get(backend); |
| | | if (map == null) |
| | | { |
| | | map = new HashMap<Long,CacheEntry>(); |
| | | map = new HashMap<>(); |
| | | map.put(entryID, cacheEntry); |
| | | idMap.put(backend, map); |
| | | } |
| | |
| | | CacheEntry ce = iterator.next(); |
| | | iterator.remove(); |
| | | |
| | | HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | Map<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | if (m != null) |
| | | { |
| | | m.remove(ce.getEntryID()); |
| | |
| | | CacheEntry ce = iterator.next(); |
| | | iterator.remove(); |
| | | |
| | | HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | Map<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | if (m != null) |
| | | { |
| | | m.remove(ce.getEntryID()); |
| | |
| | | // present and add it if it isn't. |
| | | dnMap.put(entry.getName(), cacheEntry); |
| | | |
| | | HashMap<Long,CacheEntry> map = idMap.get(backend); |
| | | Map<Long,CacheEntry> map = idMap.get(backend); |
| | | if (map == null) |
| | | { |
| | | map = new HashMap<Long,CacheEntry>(); |
| | | map = new HashMap<>(); |
| | | map.put(entryID, cacheEntry); |
| | | idMap.put(backend, map); |
| | | } |
| | |
| | | CacheEntry ce = iterator.next(); |
| | | iterator.remove(); |
| | | |
| | | HashMap<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | Map<Long,CacheEntry> m = idMap.get(ce.getBackend()); |
| | | if (m != null) |
| | | { |
| | | m.remove(ce.getEntryID()); |
| | |
| | | try |
| | | { |
| | | // Remove all references to entries for this backend from the ID cache. |
| | | HashMap<Long,CacheEntry> map = idMap.remove(backend); |
| | | Map<Long,CacheEntry> map = idMap.remove(backend); |
| | | if (map == null) |
| | | { |
| | | // No entries were in the cache for this backend, so we can return |
| | |
| | | { |
| | | // See if there are any entries for the provided backend in the cache. If |
| | | // not, then return. |
| | | HashMap<Long,CacheEntry> map = idMap.get(backend); |
| | | Map<Long,CacheEntry> map = idMap.get(backend); |
| | | if (map == null) |
| | | { |
| | | // No entries were in the cache for this backend, so we can return without |
| | |
| | | CacheEntry entry = iterator.next(); |
| | | iterator.remove(); |
| | | |
| | | HashMap<Long,CacheEntry> m = idMap.get(entry.getBackend()); |
| | | Map<Long,CacheEntry> m = idMap.get(entry.getBackend()); |
| | | if (m != null) |
| | | { |
| | | m.remove(entry.getEntryID()); |
| | |
| | | public ConfigChangeResult applyConfigurationChange( FIFOEntryCacheCfg configuration ) |
| | | { |
| | | boolean applyChanges = true; |
| | | ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>(); |
| | | List<LocalizableMessage> errorMessages = new ArrayList<>(); |
| | | EntryCacheCommon.ConfigErrorHandler errorHandler = |
| | | EntryCacheCommon.getConfigErrorHandler ( |
| | | EntryCacheCommon.ConfigPhase.PHASE_APPLY, null, errorMessages |
| | |
| | | ) |
| | | { |
| | | // Local variables to read configuration. |
| | | HashSet<SearchFilter> newIncludeFilters = null; |
| | | HashSet<SearchFilter> newExcludeFilters = null; |
| | | Set<SearchFilter> newIncludeFilters = null; |
| | | Set<SearchFilter> newExcludeFilters = null; |
| | | |
| | | // Read configuration. |
| | | DN newConfigEntryDN = configuration.dn(); |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ArrayList<Attribute> getMonitorData() |
| | | public List<Attribute> getMonitorData() |
| | | { |
| | | ArrayList<Attribute> attrs = new ArrayList<Attribute>(); |
| | | |
| | | try { |
| | | attrs = EntryCacheCommon.getGenericMonitorData( |
| | | return EntryCacheCommon.getGenericMonitorData( |
| | | Long.valueOf(cacheHits.longValue()), |
| | | // If cache misses is maintained by default cache |
| | | // get it from there and if not point to itself. |
| | |
| | | ); |
| | | } catch (Exception e) { |
| | | logger.traceException(e); |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | return attrs; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | |
| | | StringBuilder sb = new StringBuilder(); |
| | | |
| | | Map<DN,CacheEntry> dnMapCopy; |
| | | Map<Backend<?>, HashMap<Long, CacheEntry>> idMapCopy; |
| | | Map<Backend<?>, Map<Long, CacheEntry>> idMapCopy; |
| | | |
| | | // Grab cache lock to prevent any modifications |
| | | // to the cache maps until a snapshot is taken. |
| | |
| | | // Examining the real maps will hold the lock and can cause map |
| | | // modifications in case of any access order maps, make copies |
| | | // instead. |
| | | dnMapCopy = new LinkedHashMap<DN,CacheEntry>(dnMap); |
| | | idMapCopy = new HashMap<Backend<?>, HashMap<Long, CacheEntry>>(idMap); |
| | | dnMapCopy = new LinkedHashMap<>(dnMap); |
| | | idMapCopy = new HashMap<>(idMap); |
| | | } finally { |
| | | cacheWriteLock.unlock(); |
| | | } |