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.kernel.concurrent;
016    
017    import com.liferay.portal.kernel.memory.FinalizeAction;
018    import com.liferay.portal.kernel.memory.FinalizeManager;
019    import com.liferay.portal.kernel.memory.FinalizeManager.ReferenceFactory;
020    
021    import java.lang.ref.Reference;
022    
023    import java.util.Map;
024    import java.util.concurrent.ConcurrentHashMap;
025    import java.util.concurrent.ConcurrentMap;
026    
027    /**
028     * @author Shuyang Zhou
029     */
030    public class ConcurrentReferenceValueHashMap<K, V>
031            extends ConcurrentMapperHashMap<K, K, V, Reference<V>> {
032    
033            public ConcurrentReferenceValueHashMap(
034                    ConcurrentMap<K, Reference<V>> innerConcurrentMap,
035                    ReferenceFactory referenceFactory) {
036    
037                    super(innerConcurrentMap);
038    
039                    _referenceFactory = referenceFactory;
040            }
041    
042            public ConcurrentReferenceValueHashMap(
043                    int initialCapacity, float loadFactor, int concurrencyLevel,
044                    ReferenceFactory referenceFactory) {
045    
046                    this(
047                            new ConcurrentHashMap<K, Reference<V>>(
048                                    initialCapacity, loadFactor, concurrencyLevel),
049                            referenceFactory);
050            }
051    
052            public ConcurrentReferenceValueHashMap(
053                    int initialCapacity, ReferenceFactory referenceFactory) {
054    
055                    this(
056                            new ConcurrentHashMap<K, Reference<V>>(initialCapacity),
057                            referenceFactory);
058            }
059    
060            public ConcurrentReferenceValueHashMap(
061                    Map<? extends K, ? extends V> map, ReferenceFactory referenceFactory) {
062    
063                    this(new ConcurrentHashMap<K, Reference<V>>(), referenceFactory);
064    
065                    putAll(map);
066            }
067    
068            public ConcurrentReferenceValueHashMap(ReferenceFactory referenceFactory) {
069                    this(new ConcurrentHashMap<K, Reference<V>>(), referenceFactory);
070            }
071    
072            @Override
073            protected K mapKey(K key) {
074                    return key;
075            }
076    
077            @Override
078            protected K mapKeyForQuery(K key) {
079                    return key;
080            }
081    
082            @Override
083            protected Reference<V> mapValue(K key, V value) {
084                    return FinalizeManager.register(
085                            value, new RemoveEntryFinalizeAction(key), _referenceFactory);
086            }
087    
088            @Override
089            protected Reference<V> mapValueForQuery(V value) {
090                    return _referenceFactory.createReference(value, null);
091            }
092    
093            @Override
094            protected K unmapKey(K key) {
095                    return key;
096            }
097    
098            @Override
099            protected K unmapKeyForQuery(K key) {
100                    return key;
101            }
102    
103            @Override
104            protected V unmapValue(Reference<V> reference) {
105                    V value = reference.get();
106    
107                    reference.clear();
108    
109                    return value;
110            }
111    
112            @Override
113            protected V unmapValueForQuery(Reference<V> reference) {
114                    return reference.get();
115            }
116    
117            private final ReferenceFactory _referenceFactory;
118    
119            private class RemoveEntryFinalizeAction implements FinalizeAction {
120    
121                    public RemoveEntryFinalizeAction(K key) {
122                            _key = key;
123                    }
124    
125                    @Override
126                    public void doFinalize(Reference<?> reference) {
127                            remove(_key);
128                    }
129    
130                    private final K _key;
131    
132            }
133    
134    }