|
Lift Framework example source code file (SoftReferenceCache.scala)
The Lift Framework SoftReferenceCache.scala source code/* * Copyright 2007-2011 WorldWide Conferencing, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.liftweb package util import java.lang.ref.{ReferenceQueue, SoftReference}; import java.util._ import Map._ import concurrent.locks._ import common._ import util._ import Helpers._ import Schedule._ import java.lang.Thread._ /** * Companion module that has the role of monitoring garbage collected references and remove the orphaned * keys from the cache. The monitor is started by calling <i>initialize function and terminated by * calling <i>shutDown. It monitors all SoftReferenceCache instances in the context of the same classloader. * It can also be used as a factory for obtaining new instances of SoftReferenceCache class */ object SoftReferenceCache { @volatile private var terminated = false; private[util] val refQueue = new ReferenceQueue[Any](); /** * Create a new SoftReferenceCache instance */ def apply[K, V](size: Int) = new SoftReferenceCache[K, V](size) /** * Initialize the orphan keys monitor */ def initialize = { // A daemon thread is more approapriate here then an Actor as // we'll do blocking reads from the reference queue val thread = new Thread(new Runnable() { def run() { processQueue } }) thread.setDaemon(true) thread setContextClassLoader null thread.start } /** * ShutDown the monitoring */ def shutDown = { terminated = true; } private def processQueue { while (!terminated) { tryo { // Wait 30 seconds for something to appear in the queue. val sftVal = refQueue.remove(30000).asInstanceOf[SoftValue[_, _]]; if (sftVal != null) { sftVal.cache.remove(sftVal.key); } } } } } case object ProcessQueue case object Done /** * A Map that holds the values as SoftReference-s. It also applies a LRU policy for the cache entries. */ class SoftReferenceCache[K, V](cacheSize: Int) { val cache = new LinkedHashMap[K, SoftValue[K, V]]() { override def removeEldestEntry(eldest: Entry[K, SoftValue[K, V]]): Boolean = { return size() > cacheSize; } } val rwl = new ReentrantReadWriteLock(); val readLock = rwl.readLock val writeLock = rwl.writeLock private def lock[T](l: Lock)(block: => T): T = { l lock; try { block } finally { l unlock } } /** * Returns the cached value mapped with this key or Empty if not found * * @param key * @return Box[V] */ def apply(key: K): Box[V] = lock(readLock) { Box.!!(cache.get(key)) match { case Full(value) => Box.!!(value.get) or { remove(key); Empty } case _ => Empty } } /** * Puts a new keyed entry in cache * @param tuple: (K, V)* * @return this */ def +=(tuple: (K, V)*) = { lock(writeLock) { for (t <- tuple) yield { cache.put(t._1, new SoftValue(t._1, t._2, this, SoftReferenceCache.refQueue)); } } this } /** * Removes the cache entry mapped with this key * * @returns the value removed */ def remove(key: Any): Box[V] = { lock(writeLock) { for {value <- Box.!!(cache.remove(key).asInstanceOf[SoftValue[K, V]]) realValue <- Box.!!(value.get) } yield realValue } } def keys = cache.keySet } class SoftValue[K, V](k: K, v: V, lruCache: SoftReferenceCache[K, V], queue: ReferenceQueue[Any]) extends SoftReference[V](v, queue) { def key: K = k def cache: SoftReferenceCache[K, V] = lruCache } Other Lift Framework examples (source code examples)Here is a short list of links related to this Lift Framework SoftReferenceCache.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.