00001 package jpl.util;
00002
00003
00007 class HashedRefsEntry {
00008 int hash;
00009 Object obj;
00010 public int iref;
00011 public HashedRefsEntry next;
00012 }
00013
00014
00015 public
00016 class HashedRefs {
00020 public transient HashedRefsEntry table[];
00021
00025 private transient int count;
00026
00030 private int threshold;
00031
00035 private float loadFactor;
00036
00037 public HashedRefs(int initialCapacity, float loadFactor) {
00038 if ((initialCapacity <= 0) || (loadFactor <= 0.0)) {
00039 throw new IllegalArgumentException();
00040 }
00041 this.loadFactor = loadFactor;
00042 table = new HashedRefsEntry[initialCapacity];
00043 threshold = (int)(initialCapacity * loadFactor);
00044 }
00045
00046 public HashedRefs(int initialCapacity) {
00047 this(initialCapacity, 0.75f);
00048 }
00049
00050 public HashedRefs() {
00051 this(101, 0.75f);
00052 }
00053
00054 public int size() {
00055 return count;
00056 }
00057
00058 protected void rehash() {
00059 int oldCapacity = table.length;
00060 HashedRefsEntry oldTable[] = table;
00061
00062 int newCapacity = oldCapacity * 2 + 1;
00063 HashedRefsEntry newTable[] = new HashedRefsEntry[newCapacity];
00064
00065 threshold = (int)(newCapacity * loadFactor);
00066 table = newTable;
00067
00068 for (int i = oldCapacity ; i-- > 0 ;) {
00069 for (HashedRefsEntry old = oldTable[i] ; old != null ; ) {
00070 HashedRefsEntry e = old;
00071 old = old.next;
00072
00073 int index = (e.hash & 0x7FFFFFFF) % newCapacity;
00074 e.next = newTable[index];
00075 newTable[index] = e;
00076 }
00077 }
00078 }
00079
00080 public synchronized int add(Object obj, int iref) {
00081
00082 if (obj == null) {
00083 throw new NullPointerException();
00084 }
00085
00086
00087 HashedRefsEntry tab[] = table;
00088 int hash = java.lang.System.identityHashCode(obj);
00089 int index = (hash & 0x7FFFFFFF) % tab.length;
00090 for (HashedRefsEntry e = tab[index] ; e != null ; e = e.next) {
00091 if ((e.hash == hash) && (e.obj == obj)) {
00092 return e.iref;
00093 }
00094 }
00095
00096 if (count >= threshold) {
00097
00098 rehash();
00099 return add(obj, iref);
00100 }
00101
00102
00103 HashedRefsEntry e = new HashedRefsEntry();
00104 e.hash = hash;
00105 e.obj = obj;
00106 e.iref = iref;
00107 e.next = tab[index];
00108 tab[index] = e;
00109 count++;
00110 return 0;
00111 }
00112
00113 public synchronized boolean del(Object obj) {
00114 HashedRefsEntry tab[] = table;
00115 int hash = java.lang.System.identityHashCode(obj);
00116 int index = (hash & 0x7FFFFFFF) % tab.length;
00117 for (HashedRefsEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
00118 if ((e.hash == hash) && (e.obj == obj)) {
00119 if (prev != null) {
00120 prev.next = e.next;
00121 } else {
00122 tab[index] = e.next;
00123 }
00124 count--;
00125 return true;
00126 }
00127 }
00128 return false;
00129 }
00130
00131 public synchronized void clear() {
00132 HashedRefsEntry tab[] = table;
00133 for (int index = tab.length; --index >= 0; )
00134 tab[index] = null;
00135 count = 0;
00136 }
00137
00138 }