/* * Copyright 2009 Thomas Bocek * * Licensed 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 net.tomp2p.utils; import java.util.LinkedHashMap; import java.util.Map; /** * The CacheMap is a LRU cache with a given capacity. The elements that do not fit into the cache will be removed. The * flag updateEntryOnInsert will determine if {@link #put(Object, Object)} or {@link #putIfAbsent(Object, Object)} will * be used. This is useful for entries that have timing information and that should not be updated if the same key is * going to be used. This class extends {@link LinkedHashMap}, which means that this class is not thread safe. * * @author Thomas Bocek * @param <K> * The key * @param <V> * The value */ public class CacheMap<K, V> extends LinkedHashMap<K, V> { private static final long serialVersionUID = 5937613180687142367L; private final int maxEntries; private final boolean updateEntryOnInsert; /** * Creates a new CacheMap with a fixed capacity. * * @param maxEntries * The number of entries that can be stored in this map * @param updateEntryOnInsert * Set to true to update (overwrite) values. Set false to not overwrite the values if there is a value * present. */ public CacheMap(final int maxEntries, final boolean updateEntryOnInsert) { this.maxEntries = maxEntries; this.updateEntryOnInsert = updateEntryOnInsert; } @Override public V put(final K key, final V value) { if (updateEntryOnInsert) { return super.put(key, value); } else { return putIfAbsent(key, value); } } /** * If the key is not associated with a value, associate it with the value. This is the same as: * * <pre> * if (!map.containsKey(key)) { * return map.put(key, value); * } else { * return map.get(key); * } * </pre> * * @param key * key with which the value is to be associated. * @param value * value to be associated with the key. * @return previous value associated with key, or null if there was no mapping for this key. */ public V putIfAbsent(final K key, final V value) { if (!containsKey(key)) { return super.put(key, value); } else { return super.get(key); } }; @Override protected boolean removeEldestEntry(final Map.Entry<K, V> eldest) { return size() > maxEntries; } }