You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SoftHashMap.java 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* *******************************************************************
  2. * Copyright (c) 2017 Contributors
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. * ******************************************************************/package org.aspectj.util;
  9. import java.lang.ref.*;
  10. import java.util.*;
  11. public class SoftHashMap<K,V> extends AbstractMap<K,V> {
  12. private Map<K, SpecialValue> map;
  13. private ReferenceQueue<? super V> rq = new ReferenceQueue();
  14. public SoftHashMap() {
  15. this.map = new HashMap<K,SpecialValue>();
  16. }
  17. class SpecialValue extends SoftReference<V> {
  18. private final K key;
  19. SpecialValue(K k, V v) {
  20. super(v, rq);
  21. this.key = k;
  22. }
  23. }
  24. @SuppressWarnings("unchecked")
  25. private void processQueue() {
  26. SpecialValue sv = null;
  27. while ((sv = (SpecialValue)rq.poll()) != null) {
  28. map.remove(sv.key);
  29. }
  30. }
  31. @Override
  32. public V get(Object key) {
  33. SpecialValue ref = map.get(key);
  34. if (ref == null) {
  35. map.remove(key);
  36. return null;
  37. }
  38. V value = ref.get();
  39. if (value == null) {
  40. map.remove(ref.key);
  41. return null;
  42. }
  43. return value;
  44. }
  45. @Override
  46. public V put(K k, V v) {
  47. processQueue();
  48. SpecialValue sv = new SpecialValue(k, v);
  49. SpecialValue result = map.put(k, sv);
  50. return (result == null ? null : result.get());
  51. }
  52. @Override
  53. public java.util.Set<Map.Entry<K,V>> entrySet() {
  54. if (map.isEmpty()) { return Collections.<K,V>emptyMap().entrySet(); }
  55. Map<K,V> currentContents = new HashMap<K,V>();
  56. for (Map.Entry<K,SpecialValue> entry: map.entrySet()) {
  57. V currentValueForEntry = entry.getValue().get();
  58. if (currentValueForEntry != null) {
  59. currentContents.put(entry.getKey(), currentValueForEntry);
  60. }
  61. }
  62. return currentContents.entrySet();
  63. }
  64. @Override
  65. public void clear() {
  66. processQueue();
  67. map.clear();
  68. }
  69. @Override
  70. public int size() {
  71. processQueue();
  72. return map.size();
  73. }
  74. @Override
  75. public V remove(Object k) {
  76. processQueue();
  77. SpecialValue ref = map.remove(k);
  78. if (ref == null) {
  79. return null;
  80. }
  81. return ref.get();
  82. }
  83. }