/*
* This file is part of the Haven & Hearth game client.
* Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and
* Björn Johannessen <johannessen.bjorn@gmail.com>
*
* Redistribution and/or modification of this file is subject to the
* terms of the GNU Lesser General Public License, version 3, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Other parts of this source tree adhere to other copying
* rights. Please see the file `COPYING' in the root directory of the
* source tree for details.
*
* A copy the GNU Lesser General Public License is distributed along
* with the source tree of which this file is a part in the file
* `doc/LPGL-3'. If it is missing for any reason, please see the Free
* Software Foundation's website at <http://www.fsf.org/>, or write
* to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
*/
package haven;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
public class ArrayIdentity {
private static HashMap<Entry<?>, Entry<?>> set = new HashMap<Entry<?>, Entry<?>>();
private static int cleanint = 0;
private static class Entry<T> {
WeakReference<T[]> arr;
private Entry(T[] arr) {
this.arr = new WeakReference<T[]>(arr);
}
public boolean equals(Object x) {
if(!(x instanceof Entry))
return(false);
T[] a = arr.get();
if(a == null)
return(false);
Entry<?> e = (Entry<?>)x;
Object[] ea = e.arr.get();
if(ea == null)
return(false);
if(ea.length != a.length)
return(false);
for(int i = 0; i < a.length; i++) {
if(a[i] != ea[i])
return(false);
}
return(true);
}
public int hashCode() {
T[] a = arr.get();
if(a == null)
return(0);
int ret = 1;
for(T o : a)
ret = (ret * 31) + System.identityHashCode(o);
return(ret);
}
}
private static synchronized void clean() {
for(Iterator<Entry<?>> i = set.keySet().iterator(); i.hasNext();) {
Entry<?> e = i.next();
if(e.arr.get() == null)
i.remove();
}
}
@SuppressWarnings("unchecked")
private static <T> Entry<T> getcanon(Entry<T> e) {
return((Entry<T>)set.get(e));
}
public static <T> T[] intern(T[] arr) {
synchronized(ArrayIdentity.class) {
if(cleanint++ > 100) {
clean();
cleanint = 0;
}
}
Entry<T> e = new Entry<T>(arr);
synchronized(ArrayIdentity.class) {
Entry<T> e2 = getcanon(e);
T[] ret;
if(e2 == null) {
set.put(e, e);
ret = arr;
} else {
ret = e2.arr.get();
if(ret == null) {
set.remove(e2);
set.put(e, e);
ret = arr;
}
}
return(ret);
}
}
}