001 package org.mycore.frontend.indexbrowser.lucene;
002
003 import java.util.Hashtable;
004 import java.util.List;
005 import java.util.concurrent.locks.ReentrantReadWriteLock;
006
007 import org.apache.log4j.Logger;
008 import org.mycore.common.MCRCache;
009 import org.mycore.common.MCRException;
010
011 /**
012 * Caches index browser entries in a hash table. Each object type
013 * gets an entry in the table. The value of an entry is a MCRCache.
014 * This cache again creates new entries for different search and modes.
015 * So the cache key is: object index # search # mode
016 *
017 * @author Matthias Eichner
018 */
019 public class MCRIndexBrowserCache {
020 protected static Logger LOGGER = Logger.getLogger(MCRIndexBrowserCache.class);
021
022 private static Hashtable<String, MCRCache> TYPE_CACHE_TABLE = new Hashtable<String, MCRCache>();
023 private static ReentrantReadWriteLock TYPE_CACHE_TABLE_LOCK = new ReentrantReadWriteLock();
024
025 /**
026 * Add a new list of index browser entries to the cache.
027 * @param listToCache a list to cache
028 */
029 public static void addToCache(MCRIndexBrowserIncomingData browseData, String index, List<MCRIndexBrowserEntry> listToCache) {
030 if(browseData == null || index == null || listToCache == null)
031 return;
032
033 // adds a new mcr cache to the hash table
034 MCRCache mcrCache = null;
035 if(!isInHashtable(index)) {
036 mcrCache = addIndexCacheToHashtable(index);
037 } else {
038 mcrCache = getIndexCache(index);
039 }
040 // add the index browser entry list to the mcr cache
041 String cacheKey = getCacheKey(index, browseData);
042 mcrCache.put(cacheKey, listToCache);
043 }
044
045 /**
046 * Adds a new MCRCache to the hash table.
047 * @param index the key of the entry.
048 */
049 protected static MCRCache addIndexCacheToHashtable(String index) {
050 if (index == null)
051 throw new MCRException("Could not determine index: " + index);
052 MCRCache cache = null;
053 try {
054 TYPE_CACHE_TABLE_LOCK.writeLock().lock();
055 if (!TYPE_CACHE_TABLE.containsKey(index))
056 TYPE_CACHE_TABLE.put(index, cache = new MCRCache(1000, "IndexBrowser,objectType=" + index.replace(",", "_")));
057 } finally {
058 TYPE_CACHE_TABLE_LOCK.writeLock().unlock();
059 }
060 return cache;
061 }
062
063 /**
064 * Deletes a whole MCRCache from the hash table.
065 * @param objectType the object type which has to be removed
066 */
067 public static void deleteIndexCacheFromHashtable(String objectType) {
068 if (objectType == null)
069 return;
070 TYPE_CACHE_TABLE_LOCK.writeLock().lock();
071 TYPE_CACHE_TABLE.remove(objectType);
072 TYPE_CACHE_TABLE_LOCK.writeLock().unlock();
073 }
074
075 /**
076 * Returns the cached index browser list.
077 * @return the cached list.
078 */
079 public static List<MCRIndexBrowserEntry> getFromCache(String index, MCRIndexBrowserIncomingData browseData) {
080 // if the list is not cached, return null
081 if(!isCached(index, browseData))
082 return null;
083
084 String cacheKey = getCacheKey(index, browseData);
085 // get the mcr cache from the hash table
086 MCRCache mcrCache = getIndexCache(index);
087 // get the cached list from the mcr cache
088 @SuppressWarnings("unchecked")
089 List<MCRIndexBrowserEntry> cachedList = ((List<MCRIndexBrowserEntry>)mcrCache.get(cacheKey));
090 // return the list
091 return cachedList;
092 }
093
094 /**
095 * Returns the MCRCache from the hash table by the given index name.
096 * @param index the index name of the specific index browser
097 * @return a MCRCache from the hash table
098 */
099 protected static MCRCache getIndexCache(String index) {
100 try {
101 TYPE_CACHE_TABLE_LOCK.readLock().lock();
102 return TYPE_CACHE_TABLE.get(index);
103 } finally {
104 TYPE_CACHE_TABLE_LOCK.readLock().unlock();
105 }
106 }
107
108 /**
109 * Returns the cache key from the incoming browser data.
110 * @return the cache key in the form of index # search # mode
111 */
112 protected static String getCacheKey(String index, MCRIndexBrowserIncomingData browseData) {
113 String key = "";
114 if(index != null)
115 key += index;
116 key += "#";
117 if(browseData.getSearch() != null)
118 key += browseData.getSearch();
119 key += "#";
120 if(browseData.getMode() != null)
121 key += browseData.getMode();
122 return key;
123 }
124
125 /**
126 * Checks if a hash table entry with the specified index
127 * exists. If true, the method checks if the specified key
128 * exists in the MCRCache.
129 * @return true if an entry in the hash table and in the MCRCache exists,
130 * otherwise false
131 */
132 public static boolean isCached(String index, MCRIndexBrowserIncomingData browseData) {
133 String cacheKey = getCacheKey(index, browseData);
134 try {
135 TYPE_CACHE_TABLE_LOCK.readLock().lock();
136 MCRCache mcrCache = TYPE_CACHE_TABLE.get(index);
137 if (mcrCache != null && mcrCache.get(cacheKey) != null)
138 return true;
139 return false;
140 } finally {
141 TYPE_CACHE_TABLE_LOCK.readLock().unlock();
142 }
143 }
144
145 /**
146 * Checks if the entry exists in the hash table.
147 * @param key the key which will be checked
148 * @return true if the entry was found, otherwise false
149 */
150 public static boolean isInHashtable(String key) {
151 try {
152 TYPE_CACHE_TABLE_LOCK.readLock().lock();
153 return TYPE_CACHE_TABLE.containsKey(key);
154 } finally {
155 TYPE_CACHE_TABLE_LOCK.readLock().unlock();
156 }
157 }
158 }