All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.mina.util.LazyInitializedCacheMap Maven / Gradle / Ivy

/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.apache.mina.util;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.mina.core.buffer.IoBuffer;

/**
 * This map is specially useful when reads are much more frequent than writes and 
 * if the cost of instantiating the values is high like allocating an 
 * {@link IoBuffer} for example.
 *  
 * Based on the final implementation of Memoizer written by Brian Goetz and Tim
 * Peierls. This implementation will return an
 * {@link UnsupportedOperationException} on each method that is not intended to
 * be called by user code for performance reasons.
 * 
 * @param  The key type
 * @param  The value type
 * 
 * @author Apache MINA Project
 * @since MINA 2.0.0-M2
 */
public class LazyInitializedCacheMap implements Map {
    private ConcurrentMap> cache;

    /**
     * This class provides a noop {@link LazyInitializer} meaning it 
     * will return the same object it received when instantiated.
     */
    public class NoopInitializer extends LazyInitializer {
        private V value;

        /**
         * Create a new NoopInitializer instance
         * 
         * @param value The value stored in this initializer
         */
        public NoopInitializer(V value) {
            this.value = value;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public V init() {
            return value;
        }
    }

    /**
     * Default constructor. Uses the default parameters to initialize its internal
     * {@link ConcurrentHashMap}.
     */
    public LazyInitializedCacheMap() {
        this.cache = new ConcurrentHashMap<>();
    }

    /**
     * This constructor allows to provide a fine tuned {@link ConcurrentHashMap}
     * to stick with each special case the user needs.
     * 
     * @param map The map to use as a cache
     */
    public LazyInitializedCacheMap(ConcurrentHashMap> map) {
        this.cache = map;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public V get(Object key) {
        LazyInitializer c = cache.get(key);

        if (c != null) {
            return c.get();
        }

        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public V remove(Object key) {
        LazyInitializer c = cache.remove(key);
        
        if (c != null) {
            return c.get();
        }

        return null;
    }

    /**
     * If the specified key is not already associated
     * with a value, associate it with the given value.
     * This is equivalent to
     * 
     *   if (!map.containsKey(key))
     *       return map.put(key, value);
     *   else
     *       return map.get(key);
* except that the action is performed atomically. * * @param key key with which the specified value is to be associated * @param value a lazy initialized value object. * * @return the previous value associated with the specified key, * or null if there was no mapping for the key */ public V putIfAbsent(K key, LazyInitializer value) { LazyInitializer v = cache.get(key); if (v == null) { v = cache.putIfAbsent(key, value); if (v == null) { return value.get(); } } return v.get(); } /** * {@inheritDoc} */ @Override public V put(K key, V value) { LazyInitializer c = cache.put(key, new NoopInitializer(value)); if (c != null) { return c.get(); } return null; } /** * Throws {@link UnsupportedOperationException} as this method would imply * performance drops. */ @Override public boolean containsValue(Object value) { throw new UnsupportedOperationException(); } /** * Throws {@link UnsupportedOperationException} as this method would imply * performance drops. */ @Override public Collection values() { throw new UnsupportedOperationException(); } /** * Throws {@link UnsupportedOperationException} as this method would imply * performance drops. */ @Override public Set> entrySet() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ @Override public void putAll(Map m) { for (Map.Entry e : m.entrySet()) { cache.put(e.getKey(), new NoopInitializer(e.getValue())); } } /** * @return return the values from the cache */ public Collection> getValues() { return cache.values(); } /** * {@inheritDoc} */ @Override public void clear() { cache.clear(); } /** * {@inheritDoc} */ @Override public boolean containsKey(Object key) { return cache.containsKey(key); } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return cache.isEmpty(); } /** * {@inheritDoc} */ @Override public Set keySet() { return cache.keySet(); } /** * {@inheritDoc} */ @Override public int size() { return cache.size(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy