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).

sclass WeakValueMap<A, B> is AutoCloseable, IntSize {
  // A value that has been stored with this key has been garbage
  // collected.
  event valueForKeyReleased(A key);
  
  // internal
  Map<A, WeakRef<B>> map = syncMap();
  RunnablesReferenceQueue queue;
  bool myQueue = true;
  
  *() {}
  *(RunnablesReferenceQueue *queue) { myQueue = false; }
  
  class MyRef extends WeakRef<B> is Runnable {
    A key;
    
    *(A *key, B value) { super(value, queue()!); }
    
    run {
      bool current = syncMapRemoveKeyAndValuePair(map, key, this);
      
      // Note that the value may be stale (replaed by another value in
      // the meantime). If you want to distinguish that kind of event
      // from a non-stale value being released, check the variable
      // "current".
      valueForKeyReleased(key);
    }
  }
  
  // public methods follow
  
  B get(A key) {
    ret getWeakRef(map.get(key));
  }
  
  B put(A key, B value) {
    synchronized(mutex()) {
      if (value == null) {
        B old = getWeakRef(map.get(key));
        map.remove(key);
        ret old;
      } else
        ret getWeakRef(map.put(key, new MyRef(key, value)));
    }
  }
  
  O mutex() { ret collectionMutex(map); }
  
  RunnablesReferenceQueue queue() {
    synchronized(mutex()) {
      if (queue == null) queue = new RunnablesReferenceQueue;
      ret queue;
    }
  }
  
  close {
    if (myQueue)
      synchronized(mutex()) {  
        dispose queue;
      }
  }
  
  public int size() { ret map.size(); }
  
  Map<A, B> snapshot() {
    synchronized(mutex()) {
      new Map<A, B> snapshot;
      for (key, ref : map)
        mapPut(snapshot, key, getWeakRef(ref));
      ret snapshot;
    }
  }
  
  void setQueue aka queue(RunnablesReferenceQueue queue) {
    synchronized(mutex()) {  
      if (queue == null || this.queue == queue) ret;
      if (this.queue != null)
        fail("Can't change queue once we're started");
      this.queue = queue;
      myQueue = false;
    }
  }
}

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