View Javadoc

1   /*
2    * Copyright (c) 1998-2005 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  package jgroup.util;
19  
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.Map;
24  
25  import org.apache.log4j.Logger;
26  
27  /**
28   * Implementation of a map with limited access times to a key/value pair. When
29   * an entry is inserted in the map, you must specify the number of times the
30   * entry can be retrieved before it is inaccessible/removed.<p>
31   * 
32   * This map can be useful when caching objects, and you need a way to remove old
33   * items from the cache.
34   * 
35   * @author Rohnny Moland
36   */
37  public class CacheMap<K, V>
38    extends HashMap<K, V>
39  {
40    
41    ////////////////////////////////////////////////////////////////////////////////////////////
42    // Logger
43    ////////////////////////////////////////////////////////////////////////////////////////////
44  
45    private static final Logger log = Logger.getLogger(CacheMap.class);
46  
47    
48    ////////////////////////////////////////////////////////////////////////////////////////////
49    // Fields
50    ////////////////////////////////////////////////////////////////////////////////////////////
51  
52    /** The serial version uid */
53    private static final long serialVersionUID = 8045886013359387147L;
54  
55    /** Map holding access times for the cache */
56    private Map<Object, Integer> accessTimes = Collections
57        .synchronizedMap(new HashMap<Object, Integer>());
58  
59    
60    ////////////////////////////////////////////////////////////////////////////////////////////
61    // Constructor and instance methods
62    ////////////////////////////////////////////////////////////////////////////////////////////
63  
64    public CacheMap()
65    {
66      super();
67    }
68  
69  
70    /**
71     * Returns the value of the given key, if key is accessible. If not, 
72     * return null.
73     */  
74    @Override
75    public V get(Object key)
76    {
77      if (key == null)
78        return null;
79      Integer a = (Integer) accessTimes.get(key);
80      if (a == null)
81        return null;
82  
83      int access = a.intValue() - 1;
84      if (access > 1) {
85        if (log.isDebugEnabled())
86          log.debug("Access value=" + access);
87        accessTimes.put(key, new Integer(access));
88        return super.get(key);
89      } else {
90        accessTimes.remove(key);
91        return super.remove(key);
92      }
93    }
94  
95  
96    /**
97     * Insert a key/value in a <code>HashMap</code>, and set the number of
98     * times it can be accessed.
99     */
100   public void put(K key, V value, int maxAccesses)
101   {
102       if (maxAccesses > 1) {
103         accessTimes.put(key, new Integer(maxAccesses));
104         super.put(key, value);
105     }      
106   }
107 
108 
109   @Override
110   public V put(K key, V value)
111   {
112     throw new UnsupportedOperationException("put(K,V) is not supported by CacheMap");
113   }
114 
115 
116   @Override
117   public void putAll(Map<? extends K, ? extends V> m)
118   {
119     throw new UnsupportedOperationException("putAll(..) is not supported by CacheMap");
120   }
121 
122   
123   /**
124    * Clear the map. 
125    */
126   @Override
127   public void clear()
128   {
129     super.clear();
130     accessTimes.clear();
131   }
132 
133 
134   /**
135    *  Returns the size of cache map 
136    */
137   @Override
138   public int size()
139   {
140     return super.size();
141   }
142 
143 
144   @Override
145   public String toString()
146   {
147     StringBuffer buf = new StringBuffer();
148     buf.append("CacheMap.accessTimes");
149     buf.append("\n");
150     synchronized (this) {
151       for (Iterator iter = accessTimes.entrySet().iterator(); iter.hasNext();) {
152         Map.Entry entry = (Map.Entry) iter.next();
153         buf.append("[");
154         buf.append(entry.getKey());
155         buf.append("]: ");
156         buf.append(entry.getValue());
157         buf.append("\n");
158       }
159       return buf.toString();
160     }
161   }
162   
163 } // END CacheMap