Libraryless. Click here for Pure Java version (10026L/57K).
1 | sclass WeakValueMap<A, B> is AutoCloseable, IntSize {
|
2 | // A value that has been stored with this key has been garbage |
3 | // collected. |
4 | event valueForKeyReleased(A key); |
5 | |
6 | // internal |
7 | Map<A, WeakRef<B>> map = syncMap(); |
8 | RunnablesReferenceQueue queue; |
9 | bool myQueue = true; |
10 | |
11 | *() {}
|
12 | *(RunnablesReferenceQueue *queue) { myQueue = false; }
|
13 | |
14 | class MyRef extends WeakRef<B> is Runnable {
|
15 | A key; |
16 | |
17 | *(A *key, B value) { super(value, queue()!); }
|
18 | |
19 | run {
|
20 | bool current = syncMapRemoveKeyAndValuePair(map, key, this); |
21 | |
22 | // Note that the value may be stale (replaed by another value in |
23 | // the meantime). If you want to distinguish that kind of event |
24 | // from a non-stale value being released, check the variable |
25 | // "current". |
26 | valueForKeyReleased(key); |
27 | } |
28 | } |
29 | |
30 | // public methods follow |
31 | |
32 | B get(A key) {
|
33 | ret getWeakRef(map.get(key)); |
34 | } |
35 | |
36 | B put(A key, B value) {
|
37 | synchronized(mutex()) {
|
38 | if (value == null) {
|
39 | B old = getWeakRef(map.get(key)); |
40 | map.remove(key); |
41 | ret old; |
42 | } else |
43 | ret getWeakRef(map.put(key, new MyRef(key, value))); |
44 | } |
45 | } |
46 | |
47 | O mutex() { ret collectionMutex(map); }
|
48 | |
49 | RunnablesReferenceQueue queue() {
|
50 | synchronized(mutex()) {
|
51 | if (queue == null) queue = new RunnablesReferenceQueue; |
52 | ret queue; |
53 | } |
54 | } |
55 | |
56 | close {
|
57 | if (myQueue) |
58 | synchronized(mutex()) {
|
59 | dispose queue; |
60 | } |
61 | } |
62 | |
63 | public int size() { ret map.size(); }
|
64 | |
65 | Map<A, B> snapshot() {
|
66 | synchronized(mutex()) {
|
67 | new Map<A, B> snapshot; |
68 | for (key, ref : map) |
69 | mapPut(snapshot, key, getWeakRef(ref)); |
70 | ret snapshot; |
71 | } |
72 | } |
73 | |
74 | void setQueue aka queue(RunnablesReferenceQueue queue) {
|
75 | synchronized(mutex()) {
|
76 | if (queue == null || this.queue == queue) ret; |
77 | if (this.queue != null) |
78 | fail("Can't change queue once we're started");
|
79 | this.queue = queue; |
80 | myQueue = false; |
81 | } |
82 | } |
83 | } |
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
| Snippet ID: | #1035350 |
| Snippet name: | WeakValueMap - with automatic clean-up through RunnablesReferenceQueue |
| Eternal ID of this version: | #1035350/18 |
| Text MD5: | f1981ccbe25c688dd0bdb9c67a3a2450 |
| Transpilation MD5: | fcfa926c8bed2efda701008a0bd5aaa3 |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2022-05-02 13:36:11 |
| Source code size: | 2071 bytes / 83 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 709 / 893 |
| Version history: | 17 change(s) |
| Referenced in: | [show references] |