author | wenzelm |
Mon, 02 Dec 2024 22:16:29 +0100 | |
changeset 81541 | 5335b1ca6233 |
parent 81433 | c3793899b880 |
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:
73027
diff
changeset
|
18 |
def make( |
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73027
diff
changeset
|
19 |
max_string: Int = default_max_string, |
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73027
diff
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 |
|
81433
c3793899b880
performance tuning: cache for Rich_Text.format, notably for incremental tracing;
wenzelm
parents:
81429
diff
changeset
|
29 |
protected val table: JMap[Any, WeakReference[Any]] = |
73024 | 30 |
if (max_string == 0) null |
81433
c3793899b880
performance tuning: cache for Rich_Text.format, notably for incremental tracing;
wenzelm
parents:
81429
diff
changeset
|
31 |
else Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size)) |
73024 | 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" |
|
81429
0ccfc82fff57
minor performance tuning: avoid duplication of Symbol.spaces (e.g. from Pretty.formatted);
wenzelm
parents:
75393
diff
changeset
|
59 |
else if (Symbol.is_static_spaces(x)) Symbol.spaces(x.length) |
68265 | 60 |
else if (Library.is_small_int(x)) Library.signed_string_of_int(Integer.parseInt(x)) |
61 |
else { |
|
62 |
lookup(x) match { |
|
63 |
case Some(y) => y |
|
64 |
case None => |
|
65 |
val z = Library.isolate_substring(x) |
|
66 |
if (z.length > max_string) z else store(z) |
|
67 |
} |
|
68 |
} |
|
69 |
} |
|
70 |
||
71 |
// main methods |
|
73024 | 72 |
def string(x: String): String = |
73 |
if (no_cache) x else synchronized { cache_string(x) } |
|
68265 | 74 |
} |