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: | 195 / 341 |
Version history: | 17 change(s) |
Referenced in: | [show references] |