📄 fastmap.java
字号:
final Entry[][] newEntries = tmp._entries;
// Setups what is going to be the old entries.
tmp._entries = this._entries;
tmp._oldEntries = this._oldEntries;
tmp._keyComp = this._keyComp;
tmp._head = null;
tmp._tail = null;
tmp._size = -1;
// Swaps entries.
this._oldEntries = tmp;
checkpoint(); // Both this and _oldEntries have the same entries.
this._entries = newEntries; // Use new larger entry table now.
// Done. We have now a much larger entry table.
// Still, we keep reference to the old entries through oldEntries
// until the map is cleared.
}
private static final Entry[] NULL_BLOCK = new Entry[1 << FastMap.R0];
// Implements Reusable.
public void reset() {
setShared( false ); // A shared map can only be reset if no thread use it.
clear(); // In which case, it is safe to recycle the entries.
setKeyComparator( FastComparator.DEFAULT );
setValueComparator( FastComparator.DEFAULT );
}
/**
* Requires special handling during de-serialization process.
*
* @param stream the object input stream.
* @throws IOException if an I/O error occurs.
* @throws ClassNotFoundException if the class for the object de-serialized
* is not found.
*/
private void readObject(final ObjectInputStream stream) throws IOException,
ClassNotFoundException {
final int size = stream.readInt();
final int entriesLength = stream.readInt();
// Initializes transient fields.
this._entries = new FastMap.Entry[entriesLength][];
for ( int i = 0; i < this._entries.length; ) {
this._entries[i++] = FastMap.NULL_BLOCK;
}
this._head = new Entry();
this._tail = new Entry();
this._head._next = this._tail;
this._tail._previous = this._head;
this._values = new Values();
this._entrySet = new EntrySet();
this._keySet = new KeySet();
this._unmodifiable = new Unmodifiable();
setShared( stream.readBoolean() );
setKeyComparator( (FastComparator) stream.readObject() );
setValueComparator( (FastComparator) stream.readObject() );
// Reads data.
for ( int i = 0; i < size; i++ ) {
final Object/*K*/key = stream.readObject();
final Object/*V*/value = stream.readObject();
addEntry( this._keyComparator.hashCodeOf( key ),
key,
value );
}
}
/**
* Requires special handling during serialization process.
*
* @param stream the object output stream.
* @throws IOException if an I/O error occurs.
*/
private void writeObject(final ObjectOutputStream stream) throws IOException {
stream.writeInt( this._size );
stream.writeInt( this._entries.length );
stream.writeBoolean( this._isShared );
stream.writeObject( this._keyComparator );
stream.writeObject( this._values.getValueComparator() );
for ( Entry e = this._head, end = this._tail; (e = e._next) != end; ) {
stream.writeObject( e._key );
stream.writeObject( e._value );
}
}
/**
* This class represents a {@link FastMap} entry.
*/
public static final class Entry
/*<K,V>*/implements
Map.Entry/*<K,V>*/,
FastCollection.Record {
/**
* Holds the next node.
*/
private Entry /*<K,V>*/_next;
/**
* Holds the previous node.
*/
private Entry /*<K,V>*/_previous;
/**
* Holds the entry key.
*/
private Object /*K*/_key;
/**
* Holds the entry value.
*/
private Object /*V*/_value;
/**
* Holds the next entry in the same bucket.
*/
private Entry /*<K,V>*/_beside;
/**
* Holds the hash table this entry belongs to.
*/
private Entry/*<K,V>*/[][] _table;
/**
* Holds the key hash code.
*/
private int _keyHash;
/**
* Default constructor.
*/
private Entry() {
}
/**
* Returns the entry after this one.
*
* @return the next entry.
*/
public final FastCollection.Record/*Entry<K,V>*/getNext() {
return this._next;
}
/**
* Returns the entry before this one.
*
* @return the previous entry.
*/
public final FastCollection.Record/*Entry<K,V>*/getPrevious() {
return this._previous;
}
/**
* Returns the key for this entry.
*
* @return the entry key.
*/
public final Object/*K*/getKey() {
return this._key;
}
/**
* Returns the value for this entry.
*
* @return the entry value.
*/
public final Object/*V*/getValue() {
return this._value;
}
/**
* Sets the value for this entry.
*
* @param value the new value.
* @return the previous value.
*/
public final Object/*V*/setValue(final Object/*V*/value) {
final Object/*V*/old = this._value;
this._value = value;
return old;
}
/**
* Indicates if this entry is considered equals to the specified entry
* (using default value and key equality comparator to ensure symetry).
*
* @param that the object to test for equality.
* @return <code>true<code> if both entry have equal keys and values.
* <code>false<code> otherwise.
*/
public boolean equals(final Object that) {
if ( that instanceof Map.Entry ) {
final Map.Entry entry = (Map.Entry) that;
return this._key.equals( entry.getKey() ) && ((this._value != null) ? this._value.equals( entry.getValue() ) : (entry.getValue() == null));
} else {
return false;
}
}
/**
* Returns the hash code for this entry.
*
* @return this entry hash code.
*/
public int hashCode() {
return this._key.hashCode() ^ ((this._value != null) ? this._value.hashCode() : 0);
}
/**
* Detaches this entry from the entry table and list.
*/
private final void detach() {
// Removes from list.
this._previous._next = this._next;
this._next._previous = this._previous;
// Removes from bucket.
final int index = (this._keyHash >> FastMap.R0) & (this._table.length - 1);
final Entry/*<K,V>*/beside = this._beside;
Entry/*<K,V>*/previous = this._table[index][this._keyHash & FastMap.M0];
if ( previous == this ) { // First in bucket.
this._table[index][this._keyHash & FastMap.M0] = beside;
} else {
while ( previous._beside != this ) {
previous = previous._beside;
}
previous._beside = beside;
}
}
}
/**
* This class represents an read-only view over a {@link FastMap}.
*/
private final class Unmodifiable
implements
Map,
Serializable {
/**
*
*/
private static final long serialVersionUID = 2699246906507262549L;
public boolean equals(final Object obj) {
return FastMap.this.equals( obj );
}
public int hashCode() {
return FastMap.this.hashCode();
}
public String toString() {
return FastMap.this.toString();
}
public int size() {
return FastMap.this.size();
}
public boolean isEmpty() {
return FastMap.this.isEmpty();
}
public boolean containsKey(final Object key) {
return FastMap.this.containsKey( key );
}
public boolean containsValue(final Object value) {
return FastMap.this.containsValue( value );
}
public Object get(final Object key) {
return FastMap.this.get( key );
}
public Object put(final Object key,
final Object value) {
throw new UnsupportedOperationException( "Unmodifiable map" );
}
public Object remove(final Object key) {
throw new UnsupportedOperationException( "Unmodifiable map" );
}
public void putAll(final Map map) {
throw new UnsupportedOperationException( "Unmodifiable map" );
}
public void clear() {
throw new UnsupportedOperationException( "Unmodifiable map" );
}
public Set keySet() {
return (Set) FastMap.this._keySet.unmodifiable();
}
public Collection values() {
return FastMap.this._values.unmodifiable();
}
public Set entrySet() {
throw new UnsupportedOperationException( "Direct view over unmodifiable map entries is not supported " + " (to prevent access to Entry.setValue(Object) method). " + "To iterate over unmodifiable map entries, applications may "
+ "use the keySet() and values() fast collection views " + "in conjonction." );
}
}
/**
* Ensures that the compiler will not reorder previous instructions below
* this point.
*/
private static void checkpoint() {
if ( FastMap.CHECK_POINT ) {
throw new Error(); // Reads volatile.
}
}
static volatile boolean CHECK_POINT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -