📄 softsettingshash.java
字号:
SettingsEntry[] newTable = new SettingsEntry[newCapacity]; transfer(oldTable, newTable); table = newTable; /* * If ignoring null elements and processing ref queue caused massive * shrinkage, then restore old table. This should be rare, but avoids * unbounded expansion of garbage-filled tables. */ if (size >= threshold / 2) { threshold = (int)(newCapacity * LOAD_FACTOR); } else { expungeStaleEntries(); transfer(newTable, oldTable); table = oldTable; } } /** Transfer all entries from src to dest tables */ private void transfer(SettingsEntry[] src, SettingsEntry[] dest) { for (int j = 0; j < src.length; ++j) { SettingsEntry entry = src[j]; src[j] = null; while (entry != null) { SettingsEntry next = entry.next; Object key = entry.get(); if (key == null) { entry.next = null; // Help GC entry.settings = null; // " " size--; } else { int i = indexFor(entry.hash, dest.length); entry.next = dest[i]; dest[i] = entry; } entry = next; } } } /** * Removes the settings object identified by the key from this hash if * present. * * @param key key whose element is to be removed from the hash. * @return previous value associated with specified key, or <tt>null</tt> * if there was no mapping for key. */ public Object remove(String key) { if (key == null) { throw new NullPointerException("Null key"); } int hash = hash(key); expungeStaleEntries(); int i = indexFor(hash, table.length); SettingsEntry prev = table[i]; SettingsEntry entry = prev; while (entry != null) { SettingsEntry next = entry.next; if (hash == entry.hash && eq(key, entry.get())) { modCount++; size--; if (prev == entry) table[i] = next; else prev.next = next; return entry.settings; } prev = entry; entry = next; } return null; } /** * Removes all settings object from this hash. */ public void clear() { // clear out ref queue. We don't need to expunge entries // since table is getting cleared. while (queue.poll() != null) ; modCount++; SettingsEntry tab[] = table; for (int i = 0; i < tab.length; ++i) tab[i] = null; size = 0; // Allocation of array may have caused GC, which may have caused // additional entries to go stale. Removing these entries from the // reference queue will make them eligible for reclamation. while (queue.poll() != null) ; } /** * The entries in this hash extend SoftReference, using the host string * as the key. */ static class SettingsEntry extends SoftReference { private CrawlerSettings settings; private final int hash; private SettingsEntry next; /** * Create new entry. */ SettingsEntry(String key, CrawlerSettings settings, ReferenceQueue queue, int hash, SettingsEntry next) { super(key, queue); this.settings = settings; this.hash = hash; this.next = next; } public String getKey() { return (String) this.get(); } public CrawlerSettings getValue() { return settings; } public boolean equals(Object o) { if (!(o instanceof SettingsEntry)) return false; SettingsEntry e = (SettingsEntry)o; String key1 = getKey(); String key2 = e.getKey(); if (key1 == key2 || (key1 != null && key1.equals(key2))) { CrawlerSettings setting1 = getValue(); CrawlerSettings setting2 = e.getValue(); if (setting1 == setting2 || (setting1 != null && setting1.equals(setting2))) return true; } return false; } } /** Iterator over all elements in hash. */ class EntryIterator implements Iterator { int index; SettingsEntry entry = null; SettingsEntry lastReturned = null; int expectedModCount = modCount; /** * Strong reference needed to avoid disappearance of key * between hasNext and next */ String nextKey = null; /** * Strong reference needed to avoid disappearance of key * between nextEntry() and any use of the entry */ String currentKey = null; EntryIterator() { index = (size() != 0 ? table.length : 0); } public boolean hasNext() { SettingsEntry[] t = table; while (nextKey == null) { SettingsEntry e = entry; int i = index; while (e == null && i > 0) e = t[--i]; entry = e; index = i; if (e == null) { currentKey = null; return false; } nextKey = (String) e.get(); // hold on to key in strong ref if (nextKey == null) entry = entry.next; } return true; } /** The common parts of next() across different types of iterators */ public Object next() { return nextEntry(); } public SettingsEntry nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (nextKey == null && !hasNext()) throw new NoSuchElementException(); lastReturned = entry; entry = entry.next; currentKey = nextKey; nextKey = null; return lastReturned; } public void remove() { if (lastReturned == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); SoftSettingsHash.this.remove(currentKey); expectedModCount = modCount; lastReturned = null; currentKey = null; } } /** Make hash value from a String. * * @param key the string for which to create hash value. * @return the hash value. */ static int hash(String key) { int hash = key.hashCode(); hash += ~(hash << 9); hash ^= (hash >>> 14); hash += (hash << 4); hash ^= (hash >>> 10); return hash; } public EntryIterator iterator() { return new EntryIterator(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -