001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.services.cache.mru;
019:
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.Set;
026:
027: import org.sape.carbon.core.component.ComponentConfiguration;
028: import org.sape.carbon.core.component.lifecycle.Configurable;
029: import org.sape.carbon.core.component.lifecycle.Initializable;
030: import org.sape.carbon.services.cache.CacheLoadException;
031: import org.sape.carbon.services.cache.MultiGetCache;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
036: /**
037: * This class extends the AbstractMRUCache to add multi-get functionality.
038: *
039: * Copyright 2002 Sapient
040: * @since carbon 1.0
041: * @author Doug Voet, April 2002
042: * @version $Revision: 1.11 $($Author: dvoet $ / $Date: 2003/05/05 21:21:07 $)
043: */
044: public class MultiGetMRUCache extends AbstractMRUCache implements
045: MultiGetCache, MRUCache, Configurable, Initializable {
046:
047: /** The handle to Apache-commons logger */
048: private Log log = LogFactory.getLog(this .getClass());
049:
050: /** Holds the dataloader for this cache. */
051: protected MultiGetMRUCacheDataLoader dataLoader;
052:
053: /**
054: * @see org.sape.carbon.core.component.lifecycle.Configurable#configure(ComponentConfiguration)
055: */
056: public void configure(ComponentConfiguration configuration) {
057: super .configure(configuration);
058:
059: this .dataLoader = ((MultiGetMRUCacheConfiguration) configuration)
060: .getDataLoader();
061: }
062:
063: /**
064: * @see org.sape.carbon.services.cache.MultiGetCache#getMultiple(Set)
065: */
066: public Map getMultiple(Set keys) {
067: // The found keys as we retrieve them from the cache and then the loader
068: Map found = new HashMap(keys.size());
069:
070: // The set of keys that could not be immediately found in the cache
071: Set notFound = new HashSet(keys.size());
072:
073: Iterator keyIterator = keys.iterator();
074: while (keyIterator.hasNext()) {
075: Object key = keyIterator.next();
076: Object value = getObject(key); // doesn't call dataloader
077: if (value == null) {
078: // Not currently cached value - Place in map to be retrieved
079: notFound.add(key);
080: this .cacheMisses++;
081: } else {
082: // Found in current cache
083: found.put(key, value);
084: this .cacheHits++;
085: }
086: }
087:
088: // If there are keys that have not been found then
089: // look them up all at once
090: if (!notFound.isEmpty()) {
091:
092: // Seeing as how we just had a cache miss, check to see if we
093: // are loggin detailed information. If we are, then log information
094: // about the cache hit rate statistics.
095: if (log.isDebugEnabled()) {
096: log.debug("missed on cache: " + this .toString());
097: }
098:
099: try {
100: Map added = this .dataLoader.loadData(notFound);
101: found.putAll(added);
102: putAll(added);
103: } catch (CacheLoadException cle) {
104: if (log.isWarnEnabled()) {
105: log
106: .warn("Caught CacheLoadException loading data "
107: + "with keys ["
108: + notFound
109: + "], returning only data already within the cache: "
110: + cle);
111: }
112: }
113: }
114: return found;
115: }
116:
117: /**
118: * @see java.util.Map#get(Object)
119: */
120: public Object get(Object key) {
121: return getMultiple(Collections.singleton(key));
122: }
123: }
|