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.io.Serializable;
019    import java.util.HashMap;
020    import java.util.HashSet;
021    
022    /**
023     * tk.
024     * @version $Id: GroupMapImpl.java 155435 2005-02-26 13:17:27Z dirkv $
025     * @author Rodney Waldhoff
026     */
027    public class GroupMapImpl extends BaseStorageListener implements GroupMap, StorageListener {
028      /** The {@link Cache} I am associated with. */
029      protected Cache _cache = null;
030      /** A map from groups to a set of associated keys. */
031      protected HashMap _groupToKeys = new HashMap();
032      /** A map from keys to their groups. */
033      protected HashMap _keyToGroup = new HashMap();
034    
035      /** Returns an array of key values associated with the given group. */
036      public synchronized Serializable[] getKeysForGroup(Serializable group) {
037        try {
038          HashSet set = (HashSet)(_groupToKeys.get(group));
039          return (Serializable[])(set.toArray(new Serializable[0]));
040        } catch(Exception e) {
041          return new Serializable[0];
042        }
043      }
044    
045      /** Sets my cache. */
046      public void setCache(Cache c) {
047        if(null != _cache) {
048          Object mutex = _cache;
049          synchronized(mutex) {
050            synchronized(c) {
051              synchronized(this) {
052                unsetCache();
053                _cache = c;
054                _cache.registerStorageListener(this);
055              }
056            }
057          }
058        } else {
059          synchronized(c) {
060            synchronized(this) {
061              _cache = c;
062              _cache.registerStorageListener(this);
063            }
064          }
065        }
066      }
067    
068      /** Unsets my cache. */
069      public void unsetCache() {
070        if(null != _cache) {
071          Object mutex = _cache;
072          synchronized(mutex) {
073            synchronized(this) {
074              _cache.unregisterStorageListener(this);
075              clear();
076              _cache = null;
077            }
078          }
079        }
080      }
081    
082      public synchronized void stored(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group) {
083        if(null == group) {
084          Object oldgroup = _keyToGroup.get(key);
085          if(null != oldgroup) {
086            HashSet oldset = (HashSet)(_groupToKeys.get(oldgroup));
087            if(null != oldset) {
088              oldset.remove(key);
089            }
090          }
091        } else {
092          HashSet set = (HashSet)(_groupToKeys.get(group));
093          if(null != set) {
094            set.add(key);
095          } else {
096            set = new HashSet();
097            set.add(key);
098            _groupToKeys.put(group,set);
099          }
100          Object oldgroup = _keyToGroup.put(key,group);
101          if(null != oldgroup && !(oldgroup.equals(group))) {
102            HashSet oldset = (HashSet)(_groupToKeys.get(oldgroup));
103            if(null != oldset) {
104              oldset.remove(key);
105            }
106          }
107        }
108      }
109    
110      public synchronized void cleared(Serializable key) {
111        Serializable group = (Serializable)(_keyToGroup.remove(key));
112        if(null != group) {
113          HashSet set = (HashSet)(_groupToKeys.get(group));
114          set.remove(key);
115        }
116      }
117    
118      public void cleared() {
119        clear();
120      }
121    
122      protected synchronized void clear() {
123        _groupToKeys.clear();
124        _keyToGroup.clear();
125      }
126    
127      public static void main(String[] args) {
128        GroupMapImpl tm = new GroupMapImpl();
129        tm.stored("key1","val",null,null,"group1");
130        tm.stored("key2","val",null,null,"group1");
131        tm.stored("key3","val",null,null,"group1");
132        tm.stored("key4","val",null,null,"group1");
133        Serializable[] keys = tm.getKeysForGroup("group1");
134        for(int i=0;i<keys.length;i++) {
135          System.out.println(keys[i]);
136        }
137      }
138    }