Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

83
LINES

< > BotCompany Repo | #1035350 // WeakValueMap - with automatic clean-up through RunnablesReferenceQueue

JavaX fragment (include) [tags: use-pretranspiled]

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]