| 68 | 1 package fschmidt.util.java; | 
|  | 2 | 
|  | 3 import java.lang.ref.Reference; | 
|  | 4 import java.lang.ref.ReferenceQueue; | 
|  | 5 import java.lang.ref.WeakReference; | 
|  | 6 import java.util.concurrent.ConcurrentMap; | 
|  | 7 import java.util.concurrent.ConcurrentHashMap; | 
|  | 8 | 
|  | 9 | 
|  | 10 public final class Interner<T>  { | 
|  | 11 | 
|  | 12 	private static final class MyReference<T> extends WeakReference<T> { | 
|  | 13 		private final int hash; | 
|  | 14 | 
|  | 15 		MyReference(T t,ReferenceQueue<T> q) { | 
|  | 16 			super(t,q); | 
|  | 17 			hash = t.hashCode(); | 
|  | 18 		} | 
|  | 19 | 
|  | 20 		public boolean equals(Object obj) { | 
|  | 21 			if( this==obj ) | 
|  | 22 				return true; | 
|  | 23 			if( !(obj instanceof MyReference) ) | 
|  | 24 				return false; | 
|  | 25 			MyReference ref = (MyReference)obj; | 
|  | 26 			T t = this.get(); | 
|  | 27 			if( t==null ) | 
|  | 28 				return false; | 
|  | 29 			return t.equals(ref.get()); | 
|  | 30 		} | 
|  | 31 | 
|  | 32 		public int hashCode() { | 
|  | 33 			return hash; | 
|  | 34 		} | 
|  | 35 	} | 
|  | 36 | 
|  | 37 	private final ConcurrentMap<MyReference<T>,MyReference<T>> map = new ConcurrentHashMap<MyReference<T>,MyReference<T>>(); | 
|  | 38 	private ReferenceQueue<T> queue = new ReferenceQueue<T>(); | 
|  | 39 | 
|  | 40 	private void sweep() { | 
|  | 41 		while(true) { | 
|  | 42 			Reference<? extends T> ref = queue.poll(); | 
|  | 43 			if( ref == null ) | 
|  | 44 				return; | 
|  | 45 			map.remove(ref); | 
|  | 46 		} | 
|  | 47 	} | 
|  | 48 | 
|  | 49 	public T intern(T t) { | 
|  | 50 		MyReference<T> ref = new MyReference<T>(t,queue); | 
|  | 51 		while(true) { | 
|  | 52 			MyReference<T> ref2 = map.putIfAbsent(ref,ref); | 
|  | 53 			if( ref2 == null ) { | 
|  | 54 				sweep(); | 
|  | 55 				return t; | 
|  | 56 			} | 
|  | 57 			T t2 = ref2.get(); | 
|  | 58 			if( t2 != null ) { | 
|  | 59 				ref.clear(); | 
|  | 60 				return t2; | 
|  | 61 			} | 
|  | 62 		} | 
|  | 63 	} | 
|  | 64 | 
|  | 65 } |