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

143
LINES

< > BotCompany Repo | #1010613 // WeakIdentityHashMap

JavaX fragment (include)

// by Apache; modified
sclass WeakIdentityHashMap<K, V> implements Map<K, V> {
  private final ReferenceQueue<K> queue = new ReferenceQueue<K>();
  private Map<IdentityWeakReference, V> backingStore
    = new HashMap<IdentityWeakReference, V>();
    
  *() {
    _registerWeakMap(this);
  }

  public synchronized void clear() {
    backingStore.clear();
    reap();
  }

  public synchronized boolean containsKey(Object key) {
    reap();
    return backingStore.containsKey(new IdentityWeakReference(key));
  }

  public synchronized boolean containsValue(Object value)  {
    reap();
    return backingStore.containsValue(value);
  }

  public synchronized Set<Map.Entry<K, V>> entrySet() {
    reap();
    Set<Map.Entry<K, V>> ret = new HashSet<Map.Entry<K, V>>();
    for (Map.Entry<IdentityWeakReference, V> ref : backingStore.entrySet()) {
      final K key = ref.getKey().get();
      final V value = ref.getValue();
      Map.Entry<K, V> entry = new Map.Entry<K, V>() {
        public synchronized K getKey() {
          return key;
        }
        public synchronized V getValue() {
          return value;
        }
        public synchronized V setValue(V value) {
          throw new UnsupportedOperationException();
        }
      };
      ret.add(entry);
    }
    return Collections.unmodifiableSet(ret);
  }

  public synchronized Set<K> keySet() {
    reap();
    new IdentityHashMap<K, Bool> map;
    for (IdentityWeakReference ref : backingStore.keySet()) {
      K k = ref.get();
      if (k != null) map.put(k, Bool.TRUE);
    }
    return map.keySet();
  }

  public synchronized boolean equals(Object o) {
    if (!(o instanceof WeakIdentityHashMap)) {
      return false;
    }
    return backingStore.equals(((WeakIdentityHashMap)o).backingStore);
  }

  public synchronized V get(Object key) {
    reap();
    return backingStore.get(new IdentityWeakReference(key));
  }
  
  // return value seems unreliable (see ButtonImageLoader)
  public synchronized V put(K key, V value) {
    reap();
    return backingStore.put(new IdentityWeakReference(key), value);
  }

  public synchronized int hashCode() {
    reap();
    return backingStore.hashCode();
  }
  public synchronized boolean isEmpty() {
    reap();
    return backingStore.isEmpty();
  }
  public synchronized void putAll(Map t) {
    throw new UnsupportedOperationException();
  }
  
  // TODO: the IdentityWeakReference made is later enqueued,
  // even though it's not added to the map. Is that a problem?
  public synchronized V remove(Object key) {
    reap();
    return backingStore.remove(new IdentityWeakReference(key));
  }
  public synchronized int size() {
    reap();
    return backingStore.size();
  }
  public synchronized Collection<V> values() {
    reap();
    return backingStore.values();
  }

  private synchronized void reap() {
    O zombie = queue.poll();

    while (zombie != null) {
      IdentityWeakReference victim = (IdentityWeakReference) zombie;
      ifdef WeakIdentityHashMap_debug
        print("WeakIdentityHashMap removing: " + victim.get());
      endifdef
      backingStore.remove(victim);
      zombie = queue.poll();
    }
  }

  class IdentityWeakReference extends WeakReference<K> {
    int hash;

    @SuppressWarnings("unchecked")
      IdentityWeakReference(Object obj) {
      super((K)obj, queue);
      hash = System.identityHashCode(obj);
    }

    public synchronized int hashCode() {
      return hash;
    }

    public synchronized boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof WeakIdentityHashMap.IdentityWeakReference)) {
        return false;
      }
      IdentityWeakReference ref = (IdentityWeakReference)o;
      if (this.get() == ref.get()) {
        return true;
      }
      return false;
    }
  }
}

Author comment

/**
 * Implements a combination of WeakHashMap and IdentityHashMap.
 * Useful for caches that need to key off of a == comparison
 * instead of a .equals.
 *
 * <b>
 * This class is not a general-purpose Map implementation! While
 * this class implements the Map interface, it intentionally violates
 * Map's general contract, which mandates the use of the equals method
 * when comparing objects. This class is designed for use only in the
 * rare cases wherein reference-equality semantics are required.
 *
 * Note that this implementation is not synchronized.
 * </b>
 */

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1010613
Snippet name: WeakIdentityHashMap
Eternal ID of this version: #1010613/10
Text MD5: 14f1e5c9bc0f22afaded52438ab1040f
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-06-06 12:25:09
Source code size: 3959 bytes / 143 lines
Pitched / IR pitched: No / No
Views / Downloads: 455 / 1593
Version history: 9 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)