001    /*
002     * Copyright 2001-2004 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.cache;
017    
018    import java.util.HashMap;
019    import java.io.Serializable;
020    
021    /**
022     * tk.
023     * @version $Id: MemoryStash.java 155435 2005-02-26 13:17:27Z dirkv $
024     * @author Rodney Waldhoff
025     */
026    public class MemoryStash extends BaseStash implements Stash {
027      protected HashMap _hash = null;
028      protected int _maxObjs = 1000;
029      protected Cache _cache = null;
030    
031      public MemoryStash(int maxobjs) {
032        _maxObjs = maxobjs;
033        _hash = new HashMap();
034      }
035    
036      public synchronized int canStore(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group, byte[] serialized) {
037        if(_hash.size() < _maxObjs) {
038          return Stash.YES;
039        } else {
040          return Stash.NO_FULL;
041        }
042      }
043    
044      public synchronized  boolean store(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group, byte[] serialized) {
045        try {
046          _hash.put(key,new CachedObjectInfoImpl(val,expiresAt,cost));
047        } catch(Exception e) {
048          return false;
049        }
050        return true;
051      }
052    
053      public Serializable retrieve(Serializable key) {
054        // grab a lock on the cache first, since it may try to grab a lock on me
055        synchronized(_cache) {
056          synchronized(this) {
057            CachedObjectInfo info = (CachedObjectInfo)(_hash.get(key));
058            if(null != info) {
059              Long expiry = info.getExpirationTs();
060              if(null != expiry) {
061                if(expiry.longValue() < System.currentTimeMillis()) {
062                  _cache.clear(key);
063                  return null;
064                } else {
065                  return info.getKey();
066                }
067              } else {
068                return info.getKey();
069              }
070            } else {
071              return null;
072            }
073          }
074        }
075      }
076    
077      public boolean contains(Serializable key) {
078        return _hash.containsKey(key);
079      }
080    
081      public synchronized float capacity() {
082        return (((float)_hash.size())/((float)_maxObjs));
083      }
084    
085      public void clear(Serializable key) {
086        _hash.remove(key);
087      }
088    
089      public synchronized void clear() {
090        _hash.clear();
091      }
092    
093      public void setCache(Cache c) {
094        if(null != _cache) {
095          Object mutex = _cache;
096          synchronized(mutex) {
097            synchronized(this) {
098              unsetCache();
099              _cache = c;
100            }
101          }
102        } else {
103          _cache = c;
104        }
105      }
106    
107      public void unsetCache() {
108        if(null != _cache) {
109          Object mutex = _cache;
110          synchronized(mutex) {
111            clear();
112            _cache = null;
113          }
114        }
115      }
116    }