001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.collections;
025    
026    import java.util.HashMap;
027    import java.util.Map;
028    import java.util.Set;
029    
030    import org.ujmp.core.interfaces.Wrapper;
031    
032    public class CachedMap<K, V> extends AbstractMap<K, V> implements Wrapper<Map<K, V>> {
033            private static final long serialVersionUID = 1383398694858918398L;
034    
035            private transient Map<K, V> source = null;
036    
037            private transient Map<K, V> cache = null;
038    
039            public CachedMap(Map<K, V> source) {
040                    setWrappedObject(source);
041            }
042    
043            public CachedMap(Map<K, V> source, Map<K, V> cache) {
044                    setWrappedObject(source);
045                    this.cache = cache;
046            }
047    
048            public void clear() {
049                    getCache().clear();
050                    getWrappedObject().clear();
051            }
052    
053            public boolean containsKey(Object key) {
054                    if (getCache().containsKey(key)) {
055                            return true;
056                    }
057                    return getWrappedObject().containsKey(key);
058            }
059    
060            public boolean containsValue(Object value) {
061                    if (getCache().containsValue(value)) {
062                            return true;
063                    }
064                    return getWrappedObject().containsValue(value);
065            }
066    
067            @SuppressWarnings("unchecked")
068            public V get(Object key) {
069                    V value = getCache().get(key);
070                    if (value == null) {
071                            value = getWrappedObject().get(key);
072                            getCache().put((K) key, value);
073                    }
074                    return value;
075            }
076    
077            public boolean isEmpty() {
078                    if (!getCache().isEmpty()) {
079                            return false;
080                    }
081                    return getWrappedObject().isEmpty();
082            }
083    
084            public Set<K> keySet() {
085                    return getWrappedObject().keySet();
086            }
087    
088            public V put(K key, V value) {
089                    getCache().put(key, value);
090                    return getWrappedObject().put(key, value);
091            }
092    
093            public void putAll(Map<? extends K, ? extends V> m) {
094                    for (K k : m.keySet()) {
095                            put(k, m.get(k));
096                    }
097            }
098    
099            public V remove(Object key) {
100                    getCache().remove(key);
101                    return getWrappedObject().remove(key);
102            }
103    
104            public int size() {
105                    return getWrappedObject().size();
106            }
107    
108            public Map<K, V> getWrappedObject() {
109                    if (source == null) {
110                            source = new HashMap<K, V>();
111                    }
112                    return source;
113            }
114    
115            public void setWrappedObject(Map<K, V> object) {
116                    getCache().clear();
117                    this.source = object;
118            }
119    
120            public Map<K, V> getCache() {
121                    if (cache == null) {
122                            cache = new SoftHashMap<K, V>();
123                    }
124                    return cache;
125            }
126    
127    }