⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delaycache.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of// the Ozone Core License version 1 published by ozone-db.org.//// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.//// $Id: DelayCache.java,v 1.1.2.2 2004/04/10 10:06:51 per_nyfelt Exp $package org.ozoneDB.core.storage;import java.util.Collection;import java.util.Comparator;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.LinkedHashSet;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;import java.util.Map.Entry;import java.util.SortedSet;import java.util.TreeMap;import java.util.TreeSet;import java.util.logging.Level;import java.util.logging.Logger;import org.ozoneDB.OzoneInternalException;import org.ozoneDB.core.ConfigurationException;/** * <p>A cache with a fixed maximum number of objects in it. This cache grows * until it has reached its maximum, which can be set by maxCapacity. Once that * maximum has been reached, the least recently used object is thrown away when * a new object is put in the cache. This cache has, next to that maximum number * of elements, also a maximum time an element will remain in this cache. If  * that time has expired the element will be removed from this cache also.  * Reinserting an element (using the same key) causes the time for that element * to be reset.</p> * * <p>Note: every instance creates its own thread for asynchronous removal of * items past their 'best before' time. The trimmed() method on the TrimHandler * is often but not always called asynchronously from that thread.</p> *  * @author <a href="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a> * @version $Id: DelayCache.java,v 1.1.2.2 2004/04/10 10:06:51 per_nyfelt Exp $ */public class DelayCache extends AbstractTrimmingCache implements PropertyConfigurable {        private static final Logger log = Logger.getLogger(DelayCache.class.getName());    public static final PropertyInfo DELAY = new PropertyInfo(        ".delay",        "int",        "1000",        "time (in ms) that an object can stay in this cache before may be thrown out",        new String[] {"100", "10000"}    );    public static final PropertyInfo MINSLEEPTIME = new PropertyInfo(        ".minSleepTime",        "int",        "100",        "time (in ms) that the thread that does the actual removing will wait at least",        new String[] {"100", "10000"}    );    public static final PropertyInfo INITIALCAPACITY = new PropertyInfo(        ".initialCapacity",        "int",        "1",        "number of objects that this cache reserves space for initially",        new String[] {"100", "100000"}    );    public static final PropertyInfo LOADFACTOR = new PropertyInfo(        ".loadFactor",        "float, in range <0, 1>",        "0.75",        "load factor for this cache; see java.util.LinkedHashMap(int initialCapacity, float loadFactor)",        new String[] {"0.5", "0.95"}    );    private int delay;    private int minSleepTime;    private Map keysToEntries;    private SortedSet entries;    private TrimThread trimThread;        private volatile long sleepUntil;    private volatile long wakingUpAt;        public DelayCache(Properties properties, String prefix) {        super(properties, prefix);        entries = new TreeSet();        try {            float loadFactor = Float.parseFloat(properties.getProperty(prefix + LOADFACTOR.getKey(), LOADFACTOR.getDefaultValue()));            log.config(getPrefix() + " using a load factory of " + loadFactor);            int initialCapacity = Integer.parseInt(properties.getProperty(prefix + INITIALCAPACITY.getKey(), INITIALCAPACITY.getDefaultValue()));            log.config(getPrefix() + " using an initial capacity of " + initialCapacity);            keysToEntries = new LinkedHashMap(initialCapacity, loadFactor);            setDelay(Integer.parseInt(properties.getProperty(getPrefix() + DELAY.getKey(), DELAY.getDefaultValue())));            log.config(getPrefix() + " using a delay of " + getDelay());            setMinSleepTime(Integer.parseInt(properties.getProperty(getPrefix() + MINSLEEPTIME.getKey(), MINSLEEPTIME.getDefaultValue())));            log.config(getPrefix() + " using a minimum sleep time of " + getMinSleepTime());        } catch (NumberFormatException e) {            throw new ConfigurationException(e);        }        trimThread = new TrimThread();        trimThread.start();    }    protected final Map getKeysToEntries() {        return keysToEntries;    }        protected final SortedSet getEntries() {        return entries;    }    public Collection getPropertyInfos() {        Collection result = new LinkedList();        result.add(INITIALCAPACITY);        result.add(DELAY);        result.add(LOADFACTOR);        result.add(MINSLEEPTIME);        return result;    }        public Object get(Object key) {        synchronized(getSynchronizer()) {            TimedEntry entry = (TimedEntry) getKeysToEntries().get(key);            return entry == null ? null : entry.value;        }    }        public void put(Object key, Object value) {        synchronized(getSynchronizer()) {            TimedEntry entry = (TimedEntry) getKeysToEntries().get(key);            if (entry != null) {                getEntries().remove(entry);                entry.touch();            } else {                entry = new TimedEntry((Comparable) key, value);                getKeysToEntries().put(key, entry);            }            getEntries().add(entry);        }    }    public Object remove(Object key) {        synchronized(getSynchronizer()) {            TimedEntry entry = (TimedEntry) getKeysToEntries().remove(key);            getEntries().remove(entry);            return entry == null ? null : entry.value;        }    }        private void trim() {        long now = System.currentTimeMillis();        while (size() > 0) {            TimedEntry first = (TimedEntry) getEntries().first();            if (now > first.time + getDelay()) {//System.out.println("TRIMMING! " + (first.time + getDelay() - now));                getEntries().remove(first);                if (getTrimHandler() != null) {                    getTrimHandler().trimming(first.key, first.value);                }                getKeysToEntries().remove(first.key);            } else {//System.out.println("LEAVING! " + (first.time + getDelay() - now));                if (first.time + getDelay() > sleepUntil) {                    sleepUntil = first.time + getDelay();                } else {                    sleepUntil = 0;                }                break;            }        }    }        public int size() {        synchronized(getSynchronizer()) {            return getKeysToEntries().size();        }    }        public Map copyToMap() {        synchronized(getSynchronizer()) {            HashMap result = new HashMap(size());            for (Iterator i = getEntries().iterator(); i.hasNext(); ) {                TimedEntry entry = (TimedEntry) i.next();                result.put(entry.key, entry.value);            }            return result;        }    }        public final int getDelay() {        // delay is an int, so synchronization is not needed        return delay;    }        public final void setDelay(int delay) {        synchronized(getSynchronizer()) {            this.delay = delay;            trim();        }    }        public final int getMinSleepTime() {        // delay is an int, so synchronization is not needed        return minSleepTime;    }        public final void setMinSleepTime(int minSleepTime) {        synchronized(getSynchronizer()) {            this.minSleepTime = minSleepTime;            trim();        }    }        protected final class TimedEntry implements Comparable {                public long time;        public Comparable key;        public Object value;                public TimedEntry(Comparable key, Object value) {            this.key = key;            this.value = value;            touch();        }                public int compareTo(Object o) {            TimedEntry other = (TimedEntry) o;            int result = (int) (time - other.time);            return result != 0 ? result : key.compareTo(other.key);        }                public boolean equals(Object o) {            return compareTo(o) == 0;        }                public void touch() {            time = System.currentTimeMillis();        }    }        private class TrimThread extends Thread {                public TrimThread() {            super("delayed trimmer");            setDaemon(true);        }                public void run() {            synchronized(getSynchronizer()) {                for (;;) {                    long now = System.currentTimeMillis();                    try {                        getSynchronizer().wait(Math.max(sleepUntil - now, getMinSleepTime()));                    } catch (InterruptedException ignore) {                    }                    trim();                }            }        }    }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -