| author | wenzelm | 
| Fri, 24 May 2024 16:15:27 +0200 | |
| changeset 80188 | 3956e8b6a9c9 | 
| parent 75393 | 87ebf5a50283 | 
| child 81429 | 0ccfc82fff57 | 
| permissions | -rw-r--r-- | 
| 68396 | 1 | /* Title: Pure/General/cache.scala | 
| 68265 | 2 | Author: Makarius | 
| 3 | ||
| 73023 | 4 | Cache for partial sharing (weak table). | 
| 68265 | 5 | */ | 
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 73024 | 10 | import java.util.{Collections, WeakHashMap, Map => JMap}
 | 
| 68265 | 11 | import java.lang.ref.WeakReference | 
| 12 | ||
| 13 | ||
| 75393 | 14 | object Cache {
 | 
| 73024 | 15 | val default_max_string = 100 | 
| 16 | val default_initial_size = 131071 | |
| 17 | ||
| 73031 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 18 | def make( | 
| 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 19 | max_string: Int = default_max_string, | 
| 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 20 | initial_size: Int = default_initial_size): Cache = | 
| 73024 | 21 | new Cache(max_string, initial_size) | 
| 22 | ||
| 23 | val none: Cache = make(max_string = 0) | |
| 24 | } | |
| 68265 | 25 | |
| 75393 | 26 | class Cache(max_string: Int, initial_size: Int) {
 | 
| 73024 | 27 | val no_cache: Boolean = max_string == 0 | 
| 68265 | 28 | |
| 73024 | 29 | private val table: JMap[Any, WeakReference[Any]] = | 
| 30 | if (max_string == 0) null | |
| 31 | else Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size)) | |
| 32 | ||
| 33 | override def toString: String = | |
| 34 | if (no_cache) "Cache.none" else "Cache(size = " + table.size + ")" | |
| 68266 | 35 | |
| 75393 | 36 |   protected def lookup[A](x: A): Option[A] = {
 | 
| 73024 | 37 | if (table == null) None | 
| 38 |     else {
 | |
| 39 | val ref = table.get(x) | |
| 40 | if (ref == null) None | |
| 41 | else Option(ref.asInstanceOf[WeakReference[A]].get) | |
| 42 | } | |
| 68265 | 43 | } | 
| 44 | ||
| 75393 | 45 |   protected def store[A](x: A): A = {
 | 
| 73027 | 46 | if (table == null || x == null) x | 
| 73024 | 47 |     else {
 | 
| 48 | table.put(x, new WeakReference[Any](x)) | |
| 49 | x | |
| 50 | } | |
| 68265 | 51 | } | 
| 52 | ||
| 75393 | 53 |   protected def cache_string(x: String): String = {
 | 
| 73027 | 54 | if (x == null) null | 
| 55 | else if (x == "") "" | |
| 68265 | 56 | else if (x == "true") "true" | 
| 57 | else if (x == "false") "false" | |
| 58 | else if (x == "0.0") "0.0" | |
| 59 | else if (Library.is_small_int(x)) Library.signed_string_of_int(Integer.parseInt(x)) | |
| 60 |     else {
 | |
| 61 |       lookup(x) match {
 | |
| 62 | case Some(y) => y | |
| 63 | case None => | |
| 64 | val z = Library.isolate_substring(x) | |
| 65 | if (z.length > max_string) z else store(z) | |
| 66 | } | |
| 67 | } | |
| 68 | } | |
| 69 | ||
| 70 | // main methods | |
| 73024 | 71 | def string(x: String): String = | 
| 72 |     if (no_cache) x else synchronized { cache_string(x) }
 | |
| 68265 | 73 | } |