syndeticlogic.memento.AbstractPolicyStrategy.java Source code

Java tutorial

Introduction

Here is the source code for syndeticlogic.memento.AbstractPolicyStrategy.java

Source

package syndeticlogic.memento;

/*
 * Author == James Percent (james@empty-set.net) 
 *
 * Copyright 2010, 2011 James Percent
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Map;

/**
 * Class LruStrategy
 * 
 * @author <a href="mailto:james@empty-set.net">James Percent</a>
 * @version $Revision: 1.0 $
 */
public abstract class AbstractPolicyStrategy implements PolicyStrategy {

    private static final Log LOG = LogFactory.getLog(AbstractPolicyStrategy.class);
    protected final Map<Object, Object> map;
    protected final LinkedList fifo;
    protected final int maxSize;
    protected final long timeoutMillis;
    protected EvictionListener elistener;

    public static class BaseNode implements Cache.CacheNode {
        Object key;
        Object value;
        LinkedListNode fifoNode;
        long timeoutTime = 0;

        public final boolean isExpired() {
            long timeToGo = timeoutTime - System.currentTimeMillis();
            return (timeToGo <= 0);
        }

        public final Object getKey() {
            return key;
        }

        public final void setKey(Object key) {
            this.key = key;
        }

        public final Object getValue() {
            return this.value;
        }

        public final void setValue(Object value) {
            this.value = value;
        }
    }

    public AbstractPolicyStrategy(EvictionListener elistener, int maxSize, long timeoutMillis) {
        this.elistener = elistener;
        this.maxSize = maxSize;
        this.timeoutMillis = timeoutMillis;
        map = Util.createMap(maxSize);
        fifo = new LinkedList();
    }

    @Override
    public void setEvictionListener(EvictionListener elistener) {
        this.elistener = elistener;
    }

    @Override
    public Cache.CacheNode findNodeByKey(Object key) {
        return (Cache.CacheNode) map.get(key);
    }

    @Override
    public void delete(Cache.CacheNode node) {
        assert node != null && node instanceof BaseNode;
        fifo.remove(((BaseNode) node).fifoNode);
        map.remove(node.getKey());
        if (elistener != null)
            elistener.evicted(node.getKey(), node.getValue());
        node = null;
    }

    @Override
    public void removeLeastValuableNode() {
        LinkedListNode lln = null;
        Cache.CacheNode node = null;
        lln = fifo.peekLast();
        if (lln != null) {
            node = (Cache.CacheNode) lln.getValue();
            if (node != null) {
                delete(node);
                node = null;
            }
        }
    }

    @Override
    public void removeExpiredElements() {
        LinkedListNode lln = null;
        Cache.CacheNode node = null;
        while ((lln = fifo.peekLast()) != null) {
            node = (Cache.CacheNode) lln.getValue();
            if (node != null && node.isExpired()) {
                delete(node);
                node = null;
            } else {
                // not expired.. can stop now
                break;
            }
        }
    }

    @Override
    public Cache.CacheNode createNode(Object userKey, Object cacheObject) {
        assert size() <= maxSize;
        BaseNode node = (BaseNode) createNode();
        if (size() == maxSize)
            removeLeastValuableNode();

        node.setKey(userKey);
        node.setValue(cacheObject);
        node.fifoNode = fifo.addFirst(node);
        node.timeoutTime = System.currentTimeMillis() + timeoutMillis;
        map.put(userKey, node);
        return node;
    }

    @Override
    public long getTimeoutMilliSeconds() {
        return timeoutMillis;
    }

    @Override
    public int getMaxSize() {
        return maxSize;
    }

    @Override
    public int size() {
        return map.size();
    }

    public String dumpFifoKeys() {
        return dumpKeys("dumpFifoKeys: ", fifo);
    }

    protected String dumpKeys(String message, LinkedList list) {
        String dump = null;
        StringBuffer sb = new StringBuffer();
        LinkedListNode node = list.peekFirst();
        Cache.CacheNode current = null;

        while (node != null) {
            current = (Cache.CacheNode) node.getValue();
            sb.append(current.getKey());
            node = node.getNext();
        }

        dump = sb.toString();
        LOG.debug(message + dump);
        return dump;
    }
}