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

📄 lrucache.java

📁 博克后台的开发,有很多使用的方法和例子可以提供给大家学习
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		_maxCapacity = max;
	}

	/* package private members */

	/**
	 * If an entry exists in the cache, retrieve it regardless of
	 * whether it is expired.  The caller should not modify the
	 * returned object.
	 */
	synchronized Entry getEntry(Object key) {
		return (Entry)_keyOrder.get(key);
	}

	/* privates */

	/**
	 * If an entry is expired, remove it from internal data structures, otherwise
	 * update the entry's timestamp and put it back in the LRU list.  This method
	 * returns <code>true</code> if the entry was updated, or <code>false</code>
	 * if the entry was removed from the cache.
	 */
	private synchronized boolean update(Entry ent) {
		if(ent.expired()) {
			remove(ent.getKey());
			return false; // the entry was not updated
		}

		_timeOrder.remove(ent);
		ent.touch();
		_timeOrder.put(ent,ent);

		return true; // the entry was updated
	}

	/**
	 * Get an entry from the free entry pool and set the values.  If the free
	 * entry pool is empty, a new entry will be created and returned.
	 *
	 * @see returnEntryToPool(Entry ent)
	 */
	private Entry getEntryFromPool(Object key, Object obj, long expirationTime, long lifespan) {
		int last = _entryPool.size() - 1;
		if(last >= 0) {
			Entry ent = (Entry)_entryPool.remove(last);
			ent.set(key,obj,expirationTime,lifespan);
			return ent;
		}

		return new Entry(key,obj,expirationTime,lifespan);
	}

	/**
	 * Return an entry back into the free entry pool.
	 *
	 * @see getEntryFromPool(Object key, Object obj, long expirationTime, long lifespan)
	 */
	private void returnEntryToPool(Entry ent) {
		ent.reset();
		_entryPool.add(ent);
	}

	private int _maxCapacity = 32768;
	private long _lifespan;
	private long _timeout;
	private TreeMap _timeOrder;
	private HashMap _keyOrder;
	private ArrayList _entryPool;
	private static final long _DEFAULT_TIMEOUT = 1000; // 1-sec minimum timeout
	private static final long _DEFAULT_LIFESPAN = 1000; // 1-sec minimum lifespan

	/**
	 * Inner class for Cache entries. This Comparable class is
	 * consistent with equals.
	 */
	public class Entry implements Map.Entry, Comparable {

		/**
		 * Create an entry.  The timestamp for this entry is set at the
		 * time of creation.  The exiprationTime is the duration after
		 * which this entry will expire, and the lifespan is the maximum
		 * lifespan in the cache.
		 */
		private Entry(Object key, Object obj, long expirationTimeout, long lifespan) {
			set(key,obj,expirationTimeout,lifespan);
		}

		private void set(Object key, Object obj, long expirationTimeout, long lifespan) {
			_key = key;
			_obj = obj;
			_created = System.currentTimeMillis();
			_lastAccessed = _created;
			_expirationTimeout = expirationTimeout;
			_lifespan = lifespan;
		}

		/**
		 * Returns <code>true</code> if the entry is expired.  An
		 * entry is considered to be expired if it hasn't been
		 * accessed for the duration of the <code>expirationTime</code>
		 * or if it has existed longer than its <code>lifespan</code>.
		 */
		public boolean expired() {
			long currentTime = System.currentTimeMillis();

			long expirationTime = _lastAccessed + _expirationTimeout;
			long deathTime = _created + _lifespan;

			boolean expired = false;

			// If there is no overflow
			if(expirationTime > 0) {
				expired = currentTime >= expirationTime;
			} else {
				// If we overlow, the expiration time is an extremely large number
				// that the current time will never reach, so the entry cannot
				// be expired.
			}

			boolean dead = false;

			// If there is no overflow
			if(deathTime > 0) {
				dead = currentTime >= deathTime;
			} else {
				// If we overlow, the death time is an extremely large number
				// that the current time will never reach, so the entry cannot
				// be expired.
			}

			// if we're expired or dead, we call
			// that expired.
			if(expired || dead) {
				//System.out.println("Entry " + getKey() + " EXPIRED");
				return true;
			}

			return false;
		}

		/**
		 * Update this entry's last accessed time so that
		 * it does not get evicted from the cache.  This
		 * has to be done each time the object is updated
		 * in the cache.
		 */
		private void touch() {
			_lastAccessed = System.currentTimeMillis();
		}


		/**
		 * Reset this entry's object references so that the contained
		 * values can get garbage collected.
		 */
		public void reset() {
			_key = "";
			_obj = "";
		}


		/**
		 * Get the key associated with this Entry.  The <code>Object</code>
		 * returned is a <code>String</code>.
		 */
		public Object getKey() {
			return _key;
		}

		/**
		 * Get the object stored in this Entry.
		 */
		public Object getValue() {
			return _obj;
		}

		/**
		 * Set the object stored in this Entry.
		 */
		public Object setValue(Object obj) {
			Object tmp = _obj;
			_obj = obj;
			return tmp;
		}

		/**
		 * Returns the <code>hashCode</code> for this object as
		 * described in {@link java.util.Map.Entry#hashCode
		 * Map.Entry.hashCode()}
		 *
		 * @see Map.Entry#hashCode()
		 */
		public int hashCode() {
			return getKey().hashCode();
		}

		/**
		 * Get the last accessed timestamp for this object.
		 * The time is represented
		 * as the number of milliseconds since January 1, 1970,
		 * 00:00:00 GMT, the same as System.currentTimeMillis().
		 */
		protected long getLastAccessed() {
			return _lastAccessed;
		}

		private long getCreationTime() {
			return _created;
		}

		/**
		 * Return a key=value string for this entry.
		 */
		public String toString() {
			StringBuffer buf = new StringBuffer();
			buf.append(getKey() + "=" + getValue());
			return buf.toString();
		}

		/**
		 * Tests for equality of this object and <code>entry</code>
		 * This function implements as described in
		 * {@link java.util.Map.Entry#equals Map.Entry.equals()}
		 *
		 * @throws ClassCastException if <code>entry</code> is not
		 *                            an <code>Entry</code> object.
		 */
		public boolean equals(Object entry) {

			Entry ent = (Entry)entry;

			if(getKey().equals(ent.getKey()))
				return true;

			return false;
		}

		/**
		 * Implement Comparable so we can sort entries.  This function
		 * compares the last access times of the entries and imposes a total
		 * ordering on all entries.  If two entries have the same timestamps,
		 * the entries' creation timestamps are compared, and if those
		 * are equal, the key's <code>hashCode()</code>
		 * values are compared to determine a total order.
		 */
		public int compareTo(Object obj) {

			// If the keys are the same, we assume the entries are equal.
			if(equals(obj)) return 0;

			Entry ent = (Entry)obj;
			long _ts = ent.getLastAccessed();

			// This object is fresher than obj
			if(_lastAccessed > _ts)
				return -1;

			// This object is not as fresh than obj
			if(_lastAccessed < _ts)
				return 1;

			long _creation = ent.getCreationTime();

			// This object is younger than obj
			if(_creation > _ts)
				return -1;

			// This object is older than obj
			if(_creation < _ts)
				return 1;

			// If the timestamps are the same, we compare the
			// hash codes of the keys.
			int mine = _key.hashCode();
			int other = ent.getKey().hashCode();
			if(mine > other)
				return -1;
			else if(mine < other)
				return 1;

			// In this most exceedingly rare occurance, we must ensure that
			// we impose a total ordering.
			return 1;
		}

		/* privates */
		private Object _key;
		private Object _obj;
		private long _created;
		private long _expirationTimeout;
		private long _lifespan;
		private long _lastAccessed;

	}
}

⌨️ 快捷键说明

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