| 68396 |      1 | /*  Title:      Pure/General/cache.scala
 | 
| 68265 |      2 |     Author:     Makarius
 | 
|  |      3 | 
 | 
|  |      4 | cache for partial sharing (weak table).
 | 
|  |      5 | */
 | 
|  |      6 | 
 | 
|  |      7 | package isabelle
 | 
|  |      8 | 
 | 
|  |      9 | 
 | 
|  |     10 | import java.util.{Collections, WeakHashMap}
 | 
|  |     11 | import java.lang.ref.WeakReference
 | 
|  |     12 | 
 | 
|  |     13 | 
 | 
|  |     14 | class Cache(initial_size: Int = 131071, max_string: Int = 100)
 | 
|  |     15 | {
 | 
|  |     16 |   private val table =
 | 
|  |     17 |     Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size))
 | 
|  |     18 | 
 | 
|  |     19 |   def size: Int = table.size
 | 
|  |     20 | 
 | 
| 68266 |     21 |   override def toString: String = "Cache(" + size + ")"
 | 
|  |     22 | 
 | 
| 68265 |     23 |   protected def lookup[A](x: A): Option[A] =
 | 
|  |     24 |   {
 | 
|  |     25 |     val ref = table.get(x)
 | 
|  |     26 |     if (ref == null) None
 | 
|  |     27 |     else {
 | 
|  |     28 |       val y = ref.asInstanceOf[WeakReference[A]].get
 | 
|  |     29 |       if (y == null) None
 | 
|  |     30 |       else Some(y)
 | 
|  |     31 |     }
 | 
|  |     32 |   }
 | 
|  |     33 | 
 | 
|  |     34 |   protected def store[A](x: A): A =
 | 
|  |     35 |   {
 | 
|  |     36 |     table.put(x, new WeakReference[Any](x))
 | 
|  |     37 |     x
 | 
|  |     38 |   }
 | 
|  |     39 | 
 | 
|  |     40 |   protected def cache_int(x: Int): Int =
 | 
|  |     41 |     lookup(x) getOrElse store(x)
 | 
|  |     42 | 
 | 
|  |     43 |   protected def cache_string(x: String): String =
 | 
|  |     44 |   {
 | 
|  |     45 |     if (x == "") ""
 | 
|  |     46 |     else if (x == "true") "true"
 | 
|  |     47 |     else if (x == "false") "false"
 | 
|  |     48 |     else if (x == "0.0") "0.0"
 | 
|  |     49 |     else if (Library.is_small_int(x)) Library.signed_string_of_int(Integer.parseInt(x))
 | 
|  |     50 |     else {
 | 
|  |     51 |       lookup(x) match {
 | 
|  |     52 |         case Some(y) => y
 | 
|  |     53 |         case None =>
 | 
|  |     54 |           val z = Library.isolate_substring(x)
 | 
|  |     55 |           if (z.length > max_string) z else store(z)
 | 
|  |     56 |       }
 | 
|  |     57 |     }
 | 
|  |     58 |   }
 | 
|  |     59 | 
 | 
|  |     60 |   // main methods
 | 
|  |     61 |   def int(x: Int): Int = synchronized { cache_int(x) }
 | 
|  |     62 |   def string(x: String): String = synchronized { cache_string(x) }
 | 
|  |     63 | }
 |