| author | paulson | 
| Mon, 08 Nov 2021 09:31:26 +0000 | |
| changeset 74730 | 25f5f1fa31bb | 
| parent 73031 | f93f0597f4fb | 
| child 75393 | 87ebf5a50283 | 
| 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 | ||
| 73024 | 14 | object Cache | 
| 68265 | 15 | {
 | 
| 73024 | 16 | val default_max_string = 100 | 
| 17 | val default_initial_size = 131071 | |
| 18 | ||
| 73031 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 19 | def make( | 
| 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 20 | max_string: Int = default_max_string, | 
| 
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
 wenzelm parents: 
73027diff
changeset | 21 | initial_size: Int = default_initial_size): Cache = | 
| 73024 | 22 | new Cache(max_string, initial_size) | 
| 23 | ||
| 24 | val none: Cache = make(max_string = 0) | |
| 25 | } | |
| 68265 | 26 | |
| 73024 | 27 | class Cache(max_string: Int, initial_size: Int) | 
| 28 | {
 | |
| 29 | val no_cache: Boolean = max_string == 0 | |
| 68265 | 30 | |
| 73024 | 31 | private val table: JMap[Any, WeakReference[Any]] = | 
| 32 | if (max_string == 0) null | |
| 33 | else Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size)) | |
| 34 | ||
| 35 | override def toString: String = | |
| 36 | if (no_cache) "Cache.none" else "Cache(size = " + table.size + ")" | |
| 68266 | 37 | |
| 68265 | 38 | protected def lookup[A](x: A): Option[A] = | 
| 39 |   {
 | |
| 73024 | 40 | if (table == null) None | 
| 41 |     else {
 | |
| 42 | val ref = table.get(x) | |
| 43 | if (ref == null) None | |
| 44 | else Option(ref.asInstanceOf[WeakReference[A]].get) | |
| 45 | } | |
| 68265 | 46 | } | 
| 47 | ||
| 48 | protected def store[A](x: A): A = | |
| 49 |   {
 | |
| 73027 | 50 | if (table == null || x == null) x | 
| 73024 | 51 |     else {
 | 
| 52 | table.put(x, new WeakReference[Any](x)) | |
| 53 | x | |
| 54 | } | |
| 68265 | 55 | } | 
| 56 | ||
| 57 | protected def cache_string(x: String): String = | |
| 58 |   {
 | |
| 73027 | 59 | if (x == null) null | 
| 60 | else if (x == "") "" | |
| 68265 | 61 | else if (x == "true") "true" | 
| 62 | else if (x == "false") "false" | |
| 63 | else if (x == "0.0") "0.0" | |
| 64 | else if (Library.is_small_int(x)) Library.signed_string_of_int(Integer.parseInt(x)) | |
| 65 |     else {
 | |
| 66 |       lookup(x) match {
 | |
| 67 | case Some(y) => y | |
| 68 | case None => | |
| 69 | val z = Library.isolate_substring(x) | |
| 70 | if (z.length > max_string) z else store(z) | |
| 71 | } | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | // main methods | |
| 73024 | 76 | def string(x: String): String = | 
| 77 |     if (no_cache) x else synchronized { cache_string(x) }
 | |
| 68265 | 78 | } |