diff options
| author | Andrew Branson <andrew.branson@cern.ch> | 2012-05-30 08:37:45 +0200 |
|---|---|---|
| committer | Andrew Branson <andrew.branson@cern.ch> | 2012-05-30 08:37:45 +0200 |
| commit | b086f57f56bf0eb9dab9cf321a0f69aaaae84347 (patch) | |
| tree | 8e6e26e8b7eed6abad7a17b093bdbb55c5e6b1ba /src/main/java/com/c2kernel/utils/TransientCache.java | |
| parent | 22088ae8d2d5ff390518dbe1c4372325ffb3a647 (diff) | |
Initial Maven Conversion
Diffstat (limited to 'src/main/java/com/c2kernel/utils/TransientCache.java')
| -rw-r--r-- | src/main/java/com/c2kernel/utils/TransientCache.java | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/main/java/com/c2kernel/utils/TransientCache.java b/src/main/java/com/c2kernel/utils/TransientCache.java new file mode 100644 index 0000000..d58617e --- /dev/null +++ b/src/main/java/com/c2kernel/utils/TransientCache.java @@ -0,0 +1,130 @@ +
+package com.c2kernel.utils;
+import java.lang.ref.Reference;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+/**************************************************************************
+ * TransientCache - Uses transient references to allow unused entries to be
+ * reaped by the java garbage collector.
+ *
+ * $Revision: 1.1 $
+ * $Date: 2004/04/20 09:37:02 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public abstract class TransientCache<K, V> extends AbstractMap<K, V> {
+
+ private Map<K, Reference<V>> map = new Hashtable<K, Reference<V>>();
+
+ @Override
+ public synchronized Set<Entry<K, V>> entrySet() {
+ Map<K, V> newMap = new Hashtable<K,V>();
+ Iterator<Entry<K, Reference<V>>> iter = map.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry<K, Reference<V>> me = iter.next();
+ Reference<V> ref = me.getValue();
+ V o = ref.get();
+ if (o == null) {
+ // Delete cleared reference
+ iter.remove();
+ } else {
+ // Copy out interior object
+ newMap.put(me.getKey(), o);
+ }
+ }
+ // Return set of interior objects
+ return newMap.entrySet();
+ }
+
+ @Override
+ public synchronized V put(K key, V value) {
+ Reference<V> ref = makeReference(value);
+ ref = map.put(key, ref);
+ if (ref != null)
+ return (ref.get());
+ return null;
+ }
+
+ public abstract Reference<V> makeReference(Object value);
+
+ @Override
+ public V remove(Object key) {
+ Iterator<Entry<K, Reference<V>>> i = map.entrySet().iterator();
+ Entry<K, Reference<V>> correctEntry = null;
+ if (key == null) {
+ while (correctEntry == null && i.hasNext()) {
+ Entry<K, Reference<V>> e = i.next();
+ if (e.getKey() == null)
+ correctEntry = e;
+ }
+ } else {
+ while (correctEntry == null && i.hasNext()) {
+ Entry<K, Reference<V>> e = i.next();
+ if (key.equals(e.getKey()))
+ correctEntry = e;
+ }
+ }
+ V oldValue = null;
+ if (correctEntry != null) {
+ Reference<V> correctReference = correctEntry.getValue();
+ oldValue = correctReference.get();
+ i.remove();
+ }
+ return oldValue;
+ }
+ /**
+ *
+ */
+ @Override
+ public void clear() {
+ map.entrySet().clear();
+ }
+
+ private transient Set<K> keySet = null;
+
+ @Override
+ public Set<K> keySet() {
+ if (keySet == null) {
+ keySet = new AbstractSet<K>() {
+ @Override
+ public Iterator<K> iterator() {
+ return new Iterator<K>() {
+ private Iterator<Entry<K, Reference<V>>> i = map.entrySet().iterator();
+
+ @Override
+ public boolean hasNext() {
+ return i.hasNext();
+ }
+
+ @Override
+ public K next() {
+ return i.next().getKey();
+ }
+
+ @Override
+ public void remove() {
+ i.remove();
+ }
+ };
+ }
+
+ @Override
+ public int size() {
+ return TransientCache.this.size();
+ }
+
+ @Override
+ public boolean contains(Object k) {
+ return TransientCache.this.containsKey(k);
+ }
+ };
+ }
+ return keySet;
+ }
+
+}
|
