| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2012 ForgeRock AS |
| | | * Portions Copyright 2011-2013 ForgeRock AS |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | // Class database, catalog and binding for serialization. |
| | | private Database entryCacheClassDB; |
| | | private StoredClassCatalog classCatalog; |
| | | private EntryBinding entryCacheDataBinding; |
| | | private EntryBinding<FileSystemEntryCacheIndex> entryCacheDataBinding; |
| | | |
| | | // JE naming constants. |
| | | private static final String ENTRYCACHEDBNAME = "EntryCacheDB"; |
| | |
| | | // Currently registered configuration object. |
| | | private FileSystemEntryCacheCfg registeredConfiguration; |
| | | |
| | | // The maximum length of time to try to obtain a lock before giving |
| | | // up. |
| | | private long lockTimeout = LockManager.DEFAULT_TIMEOUT; |
| | | |
| | | /** |
| | | * Creates a new instance of this entry cache. |
| | | */ |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public void initializeEntryCache(FileSystemEntryCacheCfg configuration) |
| | | throws ConfigException, InitializationException { |
| | | |
| | |
| | | classCatalog = new StoredClassCatalog(entryCacheClassDB); |
| | | //This line causes an unchecked call error if the SuppressWarnings |
| | | //annotation is removed at the beginning of this method. |
| | | entryCacheDataBinding = |
| | | new SerialBinding(classCatalog, |
| | | FileSystemEntryCacheIndex.class); |
| | | entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>( |
| | | classCatalog, FileSystemEntryCacheIndex.class); |
| | | |
| | | // Get the root configuration object. |
| | | ServerManagementContext managementContext = |
| | |
| | | |
| | | if (OperationStatus.SUCCESS == |
| | | entryCacheDB.get(null, indexKey, indexData, LockMode.DEFAULT)) { |
| | | entryCacheIndex = |
| | | (FileSystemEntryCacheIndex) |
| | | entryCacheDataBinding.entryToObject(indexData); |
| | | entryCacheIndex = entryCacheDataBinding.entryToObject(indexData); |
| | | } else { |
| | | throw new CacheIndexNotFoundException(); |
| | | } |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public void finalizeEntryCache() { |
| | | |
| | | cacheWriteLock.lock(); |
| | |
| | | */ |
| | | @Override |
| | | public DN getEntryDN(Backend backend, long entryID) { |
| | | |
| | | DN entryDN = null; |
| | | cacheReadLock.lock(); |
| | | try { |
| | | // Get the map for the provided backend. If it isn't present, then |
| | | // return null. |
| | | Map map = entryCacheIndex.backendMap.get(backend.getBackendID()); |
| | | if ( !(map == null) ) { |
| | | Map<Long, String> map = entryCacheIndex.backendMap.get(backend |
| | | .getBackendID()); |
| | | if (map != null) |
| | | { |
| | | // Get the entry DN from the map by its ID. If it isn't present, |
| | | // then return null. |
| | | entryDN = DN.decode((String) map.get(entryID)); |
| | | entryDN = DN.decode(map.get(entryID)); |
| | | } |
| | | } catch (Exception e) { |
| | | // Ignore. |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public void clear() { |
| | | |
| | | cacheWriteLock.lock(); |
| | |
| | | classCatalog = new StoredClassCatalog(entryCacheClassDB); |
| | | //This line causes an unchecked call error if the SuppressWarnings |
| | | //annotation is removed at the beginning of this method. |
| | | entryCacheDataBinding = new SerialBinding(classCatalog, |
| | | FileSystemEntryCacheIndex.class); |
| | | entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>( |
| | | classCatalog, FileSystemEntryCacheIndex.class); |
| | | } |
| | | } catch (Exception e) { |
| | | if (debugEnabled()) { |
| | |
| | | ); |
| | | // Iterate through native JE properties. |
| | | try { |
| | | Map paramsMap = EnvironmentParams.SUPPORTED_PARAMS; |
| | | Map<String, ConfigParam> paramsMap = EnvironmentParams.SUPPORTED_PARAMS; |
| | | // If this entry cache is disabled then there is no open JE |
| | | // environment to check against, skip mutable check if so. |
| | | if (configuration.isEnabled()) { |
| | |
| | | if (st.countTokens() == 2) { |
| | | String jePropertyName = st.nextToken(); |
| | | String jePropertyValue = st.nextToken(); |
| | | ConfigParam param = (ConfigParam) paramsMap.get(jePropertyName); |
| | | ConfigParam param = paramsMap.get(jePropertyName); |
| | | if (!param.isMutable()) { |
| | | String oldValue = oldEnvConfig.getConfigParam(param.getName()); |
| | | String newValue = jePropertyValue; |
| | |
| | | encodeConfig = new EntryEncodeConfig(true, |
| | | newCompactEncoding, newCompactEncoding); |
| | | |
| | | setLockTimeout(newLockTimeout); |
| | | lockTimeout = newLockTimeout; |
| | | setIncludeFilters(newIncludeFilters); |
| | | setExcludeFilters(newExcludeFilters); |
| | | |
| | |
| | | ByteStringBuilder entryBytes) { |
| | | try { |
| | | // Obtain a lock on the cache. If this fails, then don't do anything. |
| | | if (!cacheWriteLock.tryLock(getLockTimeout(), TimeUnit.MILLISECONDS)) { |
| | | if (!cacheWriteLock.tryLock(lockTimeout, TimeUnit.MILLISECONDS)) { |
| | | return false; |
| | | } |
| | | // See if the current fs space usage is within acceptable constraints. If |
| | |
| | | } |
| | | |
| | | /** |
| | | * Return a verbose string representation of the current cache maps. |
| | | * This is useful primary for debugging and diagnostic purposes such |
| | | * as in the entry cache unit tests. |
| | | * @return String verbose string representation of the current cache |
| | | * maps in the following format: dn:id:backend |
| | | * one cache entry map representation per line |
| | | * or <CODE>null</CODE> if all maps are empty. |
| | | * {@inheritDoc} |
| | | */ |
| | | private String toVerboseString() |
| | | public String toVerboseString() |
| | | { |
| | | StringBuilder sb = new StringBuilder(); |
| | | |
| | |
| | | * @return boolean {@code true} if the eldest entry should be removed |
| | | * from the map; {@code false} if it should be retained. |
| | | */ |
| | | protected boolean removeEldestEntry(Map.Entry eldest) { |
| | | protected boolean removeEldestEntry(Map.Entry<String, Long> eldest) { |
| | | // Check if we hit the limit on max entries and if so remove |
| | | // the eldest entry otherwise do nothing. |
| | | if (entryCacheIndex.dnMap.size() > maxEntries.longValue()) { |
| | |
| | | cacheWriteLock.lock(); |
| | | try { |
| | | // Remove the the eldest entry from supporting maps. |
| | | String entryStringDN = (String) eldest.getKey(); |
| | | long entryID = ((Long) eldest.getValue()).longValue(); |
| | | String entryStringDN = eldest.getKey(); |
| | | long entryID = eldest.getValue(); |
| | | cacheEntryKey.setData(entryStringDN.getBytes("UTF-8")); |
| | | Set<String> backendSet = entryCacheIndex.backendMap.keySet(); |
| | | Iterator<String> backendIterator = backendSet.iterator(); |
| | |
| | | private class CacheIndexNotFoundException extends OpenDsException { |
| | | static final long serialVersionUID = 6444756053577853869L; |
| | | public CacheIndexNotFoundException() {} |
| | | public CacheIndexNotFoundException(Message message) { |
| | | super(message); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | private class CacheIndexImpairedException extends OpenDsException { |
| | | static final long serialVersionUID = -369455697709478407L; |
| | | public CacheIndexImpairedException() {} |
| | | public CacheIndexImpairedException(Message message) { |
| | | super(message); |
| | | } |
| | | } |
| | | |
| | | } |