227 }
228
229 /**
230 * Returns index of the specified hash code in the given table.
231 * Note that the table size must be a power of two.
232 *
233 * @param hash the hash code
234 * @param table the table
235 * @return an index of the specified hash code in the given table
236 */
237 private static int index(int hash, Object[] table) {
238 return hash & (table.length - 1);
239 }
240
241 /**
242 * Creates a new array for the cache entries.
243 *
244 * @param size requested capacity MUST be a power of two
245 * @return a new array for the cache entries
246 */
247 @SuppressWarnings("unchecked")
248 private CacheEntry<K,V>[] newTable(int size) {
249 return (CacheEntry<K,V>[]) new CacheEntry[size];
250 }
251
252 private V getEntryValue(K key, int hash, CacheEntry<K,V> entry) {
253 while (entry != null) {
254 if (entry.matches(hash, key)) {
255 return entry.value.getReferent();
256 }
257 entry = entry.next;
258 }
259 return null;
260 }
261
262 private void removeStaleEntries() {
263 Object reference = this.queue.poll();
264 if (reference != null) {
265 synchronized (this.queue) {
266 do {
267 if (reference instanceof Ref) {
268 Ref ref = (Ref) reference;
269 @SuppressWarnings("unchecked")
270 CacheEntry<K,V> owner = (CacheEntry<K,V>) ref.getOwner();
271 if (owner != null) {
272 int index = index(owner.hash, this.table);
273 CacheEntry<K,V> prev = this.table[index];
274 CacheEntry<K,V> entry = prev;
275 while (entry != null) {
276 CacheEntry<K,V> next = entry.next;
277 if (entry == owner) {
278 if (entry == prev) {
279 this.table[index] = next;
280 } else {
281 prev.next = next;
282 }
283 entry.unlink();
284 break;
285 }
286 prev = entry;
287 entry = next;
|
227 }
228
229 /**
230 * Returns index of the specified hash code in the given table.
231 * Note that the table size must be a power of two.
232 *
233 * @param hash the hash code
234 * @param table the table
235 * @return an index of the specified hash code in the given table
236 */
237 private static int index(int hash, Object[] table) {
238 return hash & (table.length - 1);
239 }
240
241 /**
242 * Creates a new array for the cache entries.
243 *
244 * @param size requested capacity MUST be a power of two
245 * @return a new array for the cache entries
246 */
247 @SuppressWarnings({"unchecked", "rawtypes"})
248 private CacheEntry<K,V>[] newTable(int size) {
249 return (CacheEntry<K,V>[]) new CacheEntry[size];
250 }
251
252 private V getEntryValue(K key, int hash, CacheEntry<K,V> entry) {
253 while (entry != null) {
254 if (entry.matches(hash, key)) {
255 return entry.value.getReferent();
256 }
257 entry = entry.next;
258 }
259 return null;
260 }
261
262 private void removeStaleEntries() {
263 Object reference = this.queue.poll();
264 if (reference != null) {
265 synchronized (this.queue) {
266 do {
267 if (reference instanceof Ref) {
268 @SuppressWarnings("rawtypes")
269 Ref ref = (Ref) reference;
270 @SuppressWarnings("unchecked")
271 CacheEntry<K,V> owner = (CacheEntry<K,V>) ref.getOwner();
272 if (owner != null) {
273 int index = index(owner.hash, this.table);
274 CacheEntry<K,V> prev = this.table[index];
275 CacheEntry<K,V> entry = prev;
276 while (entry != null) {
277 CacheEntry<K,V> next = entry.next;
278 if (entry == owner) {
279 if (entry == prev) {
280 this.table[index] = next;
281 } else {
282 prev.next = next;
283 }
284 entry.unlink();
285 break;
286 }
287 prev = entry;
288 entry = next;
|