/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/**
* LRUCache
* in-memory bounded cache with an LRU list
*/
// the item never expires
// LRU list
// the number of times the cache was trimmed
protected int trimCount;
protected int listSize;
protected boolean isUnbounded = false;
/**
* default constructor
*/
public LruCache() { }
/**
* constructor with specified max entries.
* @param defaultMaxEntries specifies the default max entries
* to use when the maxEntries is <= 0.
*/
this.defaultMaxEntries = defaultMaxEntries;
}
/**
* initialize the cache
* @param maxEntries maximum number of entries expected in the cache
* @param loadFactor the load factor
* @param timeout to be used to trim the expired entries
* @param props opaque list of properties for a given cache implementation
* @throws a generic Exception if the initialization failed
*/
// if the max entries is <= 0 then set the default max entries
if (maxEntries <= 0) {
// mark this cache unbounded
isUnbounded = true;
}
}
/**
* sets the timeout value
* @param timeout to be used to trim the expired entries
*/
// accept a positive timeout
if (timeout > 0)
}
/**
* create new item
* @param hashCode for the entry
* @param key <code>Object</code> key
* @param value <code>Object</code> value
* @param size size in bytes of the item
*
* subclasses may override to provide their own CacheItem extensions
* e.g. one that permits persistence.
*/
}
/**
* trim one item from the LRU list
* @param currentTime of this operation
* @return the item trimmed from cache
*
* list synchronization is handled by the caller
*/
//TODO:: print out a warning message here
} else {
}
} else {
}
trimCount++;
listSize--;
}
return trimItem;
}
/**
/**
* this item is just added to the cache
* @param item <code>CacheItem</code> that was created
* @return a overflow item; may be null
*
* this function checks if adding the new item results in a overflow;
* if so, it returns the item to be removed.
*
* Cache bucket is already synchronized by the caller
*/
boolean updateThreshold = false;
// set the timestamp
// update the LRU
synchronized (this) {
}
else {
}
listSize++;
if (isThresholdReached()) {
if (!isUnbounded)
else
updateThreshold = true;
}
}
// update the base cache threshold if needed
if (updateThreshold)
super.handleOverflow();
return overflow;
}
/**
* this item is accessed
* @param item <code>CacheItem</code> accessed
*
* Cache bucket is already synchronized by the caller
*/
synchronized (this) {
// if the item is already trimmed from the LRU list, nothing to do.
return;
// update the timestamp
// update the LRU list
// put the item at the head of LRU list
// patch up the previous neighbors
else
}
}
}
/**
* item value has been refreshed
* @param item <code>CacheItem</code> that was refreshed
* @param oldSize size of the previous value that was refreshed
* Cache bucket is already synchronized by the caller
*/
}
/**
* item value has been removed from the cache
* @param item <code>CacheItem</code> that was just removed
*
* Cache bucket is already synchronized by the caller
*/
// remove the item from the LRU list
synchronized (this) {
// if the item is already trimmed from the LRU list, nothing to do.
if (l.isTrimmed)
return;
else
else
listSize--;
}
}
/**
* trim the expired entries from the cache.
* @param maxCount maximum number of invalid entries to trim
* specify Integer.MAX_VALUE to trim all invalid entries
* This call is to be scheduled by a thread managed by the container.
*
* NOTE: this algorithm assumes that all the entries in the cache have
* identical timeout (otherwise traversing from tail won't be right).
*/
int count = 0;
synchronized (this) {
// traverse LRU list till we reach a valid item; remove them at once
if (timeout != NO_TIMEOUT &&
count++;
} else
break;
}
// if there was at least one invalid item then item != tail.
else
}
}
// trim the items from the BaseCache from the old tail backwards
}
}
/**
* get generic stats from subclasses
*/
/**
* get the desired statistic counter
* @param key to corresponding stat
* @return an Object corresponding to the stat
* See also: Constant.java for the key
*/
}
return stat;
}
return stats;
}
/** default CacheItem class implementation ***/
// double linked LRU list
protected boolean isTrimmed;
protected long lastAccessed;
}
}
}