/******************************************************************************* * Copyright (c) 2010-2014 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation *******************************************************************************/ package org.eclipse.skalli.core.cache; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Map; import java.util.Map.Entry; /** * Implementation of the "Groundhog" cache strategy. * <p> * This cache remembers the point in time when each entry was read for the last time. * The entry which was not accessed for the longest period of time will be discarded, * if there is a need to do so. * <p> * Furthermore, this cache remembers its data only for the current day. * The next day it starts over empty again. * <p> * For more details ask Phil Connors (a.k.a. Bill Murray). * * @param <K> type of the key. * @param <V> type of the value. */ public class GroundhogCache<K, V> extends CacheBase<K, V, Long> { private int activeDayOfYear; private int activeYear; public GroundhogCache(int cacheSize) { super(cacheSize); initializeIfNeeded(); } public GroundhogCache(int cacheSize, Cache<K, V> cache) { super(cacheSize, cache); initializeIfNeeded(); } Calendar getCalendar() { return new GregorianCalendar(); } private void initializeIfNeeded() { Calendar cal = getCalendar(); int dayOfYear = cal.get(Calendar.DAY_OF_YEAR); int year = cal.get(Calendar.YEAR); if (dayOfYear != activeDayOfYear || year != activeYear) { activeDayOfYear = dayOfYear; activeYear = year; clear(); } } @Override protected Long createMetaInfo(K key) { return System.nanoTime(); } @Override protected void beforeAccess(K key) { initializeIfNeeded(); }; @Override protected Long onAccess(K key, Long metaInfo) { return System.nanoTime(); } @Override protected K calcEntryToDiscard(Map<K, Long> metaInfos) { long oldest = System.nanoTime(); K oldestEntryKey = null; for (Entry<K, Long> entry : metaInfos.entrySet()) { if (entry.getValue() < oldest) { oldestEntryKey = entry.getKey(); oldest = entry.getValue(); } } return oldestEntryKey; } }