001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.cache.memory;
016    
017    import com.liferay.portal.kernel.cache.AbstractPortalCache;
018    import com.liferay.portal.kernel.cache.PortalCacheManager;
019    
020    import java.io.Serializable;
021    
022    import java.util.ArrayList;
023    import java.util.List;
024    import java.util.concurrent.ConcurrentHashMap;
025    import java.util.concurrent.ConcurrentMap;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     * @author Edward Han
030     * @author Shuyang Zhou
031     */
032    public class MemoryPortalCache<K extends Serializable, V>
033            extends AbstractPortalCache<K, V> {
034    
035            public MemoryPortalCache(
036                    PortalCacheManager<K, V> portalCacheManager, String name,
037                    int initialCapacity) {
038    
039                    _portalCacheManager = portalCacheManager;
040                    _name = name;
041    
042                    _concurrentMap = new ConcurrentHashMap<K, V>(initialCapacity);
043            }
044    
045            public void destroy() {
046                    removeAll();
047    
048                    _concurrentMap = null;
049                    _name = null;
050            }
051    
052            @Override
053            public List<K> getKeys() {
054                    List<K> keys = new ArrayList<K>();
055    
056                    for (K key : _concurrentMap.keySet()) {
057                            keys.add(key);
058                    }
059    
060                    return keys;
061            }
062    
063            @Override
064            public String getName() {
065                    return _name;
066            }
067    
068            @Override
069            public PortalCacheManager<K, V> getPortalCacheManager() {
070                    return _portalCacheManager;
071            }
072    
073            @Override
074            public void removeAll() {
075                    _concurrentMap.clear();
076    
077                    aggregatedCacheListener.notifyRemoveAll(this);
078            }
079    
080            @Override
081            protected V doGet(K key) {
082                    return _concurrentMap.get(key);
083            }
084    
085            @Override
086            protected void doPut(K key, V value, int timeToLive, boolean quiet) {
087                    V oldValue = _concurrentMap.put(key, value);
088    
089                    if (quiet) {
090                            return;
091                    }
092    
093                    if (oldValue != null) {
094                            aggregatedCacheListener.notifyEntryUpdated(
095                                    this, key, value, timeToLive);
096                    }
097                    else {
098                            aggregatedCacheListener.notifyEntryPut(
099                                    this, key, value, timeToLive);
100                    }
101            }
102    
103            @Override
104            protected V doPutIfAbsent(K key, V value, int timeToLive) {
105                    V oldValue = _concurrentMap.putIfAbsent(key, value);
106    
107                    if (oldValue == null) {
108                            aggregatedCacheListener.notifyEntryPut(
109                                    this, key, value, timeToLive);
110                    }
111    
112                    return oldValue;
113            }
114    
115            @Override
116            protected void doRemove(K key) {
117                    V value = _concurrentMap.remove(key);
118    
119                    if (value != null) {
120                            aggregatedCacheListener.notifyEntryRemoved(
121                                    this, key, value, DEFAULT_TIME_TO_LIVE);
122                    }
123            }
124    
125            @Override
126            protected boolean doRemove(K key, V value) {
127                    boolean removed = _concurrentMap.remove(key, value);
128    
129                    if (removed) {
130                            aggregatedCacheListener.notifyEntryRemoved(
131                                    this, key, value, DEFAULT_TIME_TO_LIVE);
132                    }
133    
134                    return removed;
135            }
136    
137            @Override
138            protected V doReplace(K key, V value, int timeToLive) {
139                    V oldValue = _concurrentMap.replace(key, value);
140    
141                    if (oldValue != null) {
142                            aggregatedCacheListener.notifyEntryUpdated(
143                                    this, key, value, timeToLive);
144                    }
145    
146                    return oldValue;
147            }
148    
149            @Override
150            protected boolean doReplace(K key, V oldValue, V newValue, int timeToLive) {
151                    boolean replaced = _concurrentMap.replace(key, oldValue, newValue);
152    
153                    if (replaced) {
154                            aggregatedCacheListener.notifyEntryUpdated(
155                                    this, key, newValue, timeToLive);
156                    }
157    
158                    return replaced;
159            }
160    
161            private ConcurrentMap<K, V> _concurrentMap;
162            private String _name;
163            private final PortalCacheManager<K, V> _portalCacheManager;
164    
165    }