Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a SoftHashMap in Scala?

I'm aware of this question for java, but none of those implementations seem to play well with scala.collection.JavaConversions.

I'm looking for something simple (e.g. single file, not a whole library) that implements SoftHashMap such that it plays well with Scala Map (i.e. supports getOrElseUpdate, unzip, and the remaining Scala Map methods).

like image 538
dsg Avatar asked Feb 25 '11 00:02

dsg


People also ask

Does Scala have HashMap?

HashMap is a part of Scala Collection's. It is used to store element and return a map. A HashMap is a combination of key and value pairs which are stored using a Hash Table data structure. It provides the basic implementation of Map.

What does map return in Scala?

map() method is a member of TraversableLike trait, it is used to run a predicate method on each elements of a collection. It returns a new collection.

How do you access map elements in Scala?

Scala Map get() method with exampleThe get() method is utilized to give the value associated with the keys of the map. The values are returned here as an Option i.e, either in form of Some or None. Return Type: It returns the keys corresponding to the values given in the method as argument.


2 Answers

Implementation inspired by this java WeakHashMap:

import scala.collection.mutable.{Map, HashMap}
import scala.ref._


class SoftMap[K, V <: AnyRef] extends Map[K, V]
{
  class SoftValue[K, +V <: AnyRef](val key:K, value:V, queue:ReferenceQueue[V]) extends SoftReference(value, queue)

  private val map = new HashMap[K, SoftValue[K, V]]

  private val queue = new ReferenceQueue[V]

  override def += (kv: (K, V)): this.type =
  {
    processQueue
    val sv = new SoftValue(kv._1, kv._2, queue)
    map(kv._1) = sv
    this
  }

  private def processQueue
  {
    while (true)
    {
      queue.poll match
      {   
        case Some(sv:SoftValue[K, _]) => map.remove(sv.key)
        case _ => return
      }
    }
  }


  override def get(key: K): Option[V] = map.get(key) match
  {
    case Some(sv) => sv.get match
      { case v:Some[_] => v
        case None => {map.remove(key); None} }
    case None => None
  }



  override def -=(key: K):this.type =
  {
    processQueue
    map.remove(key)
    this
  }

  override def iterator: Iterator[(K, V)] =
  {
    processQueue
    map.iterator.collect{ case (key, sv) if sv.get.isDefined => (key, sv.get.get) }
  }

  override def empty:SoftMap[K, V] = new SoftMap[K, V]

  override def size = {processQueue; map.size}
}
like image 158
dsg Avatar answered Sep 19 '22 15:09

dsg


I found one in liftweb.

I do not use it yet, so check it yourself please.

http://scala-tools.org/mvnsites/liftweb-2.4-M5/net/liftweb/util/SoftReferenceCache.html

like image 42
iron9light Avatar answered Sep 18 '22 15:09

iron9light