///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
// Copyright (c) 2009, Rob Eden All Rights Reserved.
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
///////////////////////////////////////////////////////////////////////////////
package gnu.trove.map.hash;
//////////////////////////////////////////////////
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
//////////////////////////////////////////////////
import gnu.trove.map.TShortByteMap;
import gnu.trove.function.TByteFunction;
import gnu.trove.procedure.*;
import gnu.trove.set.*;
import gnu.trove.iterator.*;
import gnu.trove.iterator.hash.*;
import gnu.trove.impl.hash.*;
import gnu.trove.impl.HashFunctions;
import gnu.trove.*;
import java.io.*;
import java.util.*;
/**
* An open addressed Map implementation for short keys and byte values.
*
* @author Eric D. Friedman
* @author Rob Eden
* @author Jeff Randall
* @version $Id: _K__V_HashMap.template,v 1.1.2.16 2010/03/02 04:09:50 robeden Exp $
*/
public class TShortByteHashMap extends TShortByteHash implements TShortByteMap, Externalizable {
static final long serialVersionUID = 1L;
/** the values of the map */
protected transient byte[] _values;
/**
* Creates a new <code>TShortByteHashMap</code> instance with the default
* capacity and load factor.
*/
public TShortByteHashMap() {
super();
}
/**
* Creates a new <code>TShortByteHashMap</code> instance with a prime
* capacity equal to or greater than <tt>initialCapacity</tt> and
* with the default load factor.
*
* @param initialCapacity an <code>int</code> value
*/
public TShortByteHashMap( int initialCapacity ) {
super( initialCapacity );
}
/**
* Creates a new <code>TShortByteHashMap</code> instance with a prime
* capacity equal to or greater than <tt>initialCapacity</tt> and
* with the specified load factor.
*
* @param initialCapacity an <code>int</code> value
* @param loadFactor a <code>float</code> value
*/
public TShortByteHashMap( int initialCapacity, float loadFactor ) {
super( initialCapacity, loadFactor );
}
/**
* Creates a new <code>TShortByteHashMap</code> instance with a prime
* capacity equal to or greater than <tt>initialCapacity</tt> and
* with the specified load factor.
*
* @param initialCapacity an <code>int</code> value
* @param loadFactor a <code>float</code> value
* @param noEntryKey a <code>short</code> value that represents
* <tt>null</tt> for the Key set.
* @param noEntryValue a <code>byte</code> value that represents
* <tt>null</tt> for the Value set.
*/
public TShortByteHashMap( int initialCapacity, float loadFactor,
short noEntryKey, byte noEntryValue ) {
super( initialCapacity, loadFactor, noEntryKey, noEntryValue );
}
/**
* Creates a new <code>TShortByteHashMap</code> instance containing
* all of the entries in the map passed in.
*
* @param keys a <tt>short</tt> array containing the keys for the matching values.
* @param values a <tt>byte</tt> array containing the values.
*/
public TShortByteHashMap( short[] keys, byte[] values ) {
super( Math.max( keys.length, values.length ) );
int size = Math.min( keys.length, values.length );
for ( int i = 0; i < size; i++ ) {
this.put( keys[i], values[i] );
}
}
/**
* Creates a new <code>TShortByteHashMap</code> instance containing
* all of the entries in the map passed in.
*
* @param map a <tt>TShortByteMap</tt> that will be duplicated.
*/
public TShortByteHashMap( TShortByteMap map ) {
super( map.size() );
if ( map instanceof TShortByteHashMap ) {
TShortByteHashMap hashmap = ( TShortByteHashMap ) map;
this._loadFactor = hashmap._loadFactor;
this.no_entry_key = hashmap.no_entry_key;
this.no_entry_value = hashmap.no_entry_value;
//noinspection RedundantCast
if ( this.no_entry_key != ( short ) 0 ) {
Arrays.fill( _set, this.no_entry_key );
}
//noinspection RedundantCast
if ( this.no_entry_value != ( byte ) 0 ) {
Arrays.fill( _values, this.no_entry_value );
}
setUp( (int) Math.ceil( DEFAULT_CAPACITY / _loadFactor ) );
}
putAll( map );
}
/**
* initializes the hashtable to a prime capacity which is at least
* <tt>initialCapacity + 1</tt>.
*
* @param initialCapacity an <code>int</code> value
* @return the actual capacity chosen
*/
protected int setUp( int initialCapacity ) {
int capacity;
capacity = super.setUp( initialCapacity );
_values = new byte[capacity];
return capacity;
}
/**
* rehashes the map to the new capacity.
*
* @param newCapacity an <code>int</code> value
*/
/** {@inheritDoc} */
protected void rehash( int newCapacity ) {
int oldCapacity = _set.length;
short oldKeys[] = _set;
byte oldVals[] = _values;
byte oldStates[] = _states;
_set = new short[newCapacity];
_values = new byte[newCapacity];
_states = new byte[newCapacity];
for ( int i = oldCapacity; i-- > 0; ) {
if( oldStates[i] == FULL ) {
short o = oldKeys[i];
int index = insertionIndex( o );
_set[index] = o;
_values[index] = oldVals[i];
_states[index] = FULL;
}
}
}
/** {@inheritDoc} */
public byte put( short key, byte value ) {
int index = insertionIndex( key );
return doPut( key, value, index );
}
/** {@inheritDoc} */
public byte putIfAbsent( short key, byte value ) {
int index = insertionIndex( key );
if (index < 0)
return _values[-index - 1];
return doPut( key, value, index );
}
private byte doPut( short key, byte value, int index ) {
byte previousState;
byte previous = no_entry_value;
boolean isNewMapping = true;
if ( index < 0 ) {
index = -index -1;
previous = _values[index];
isNewMapping = false;
}
previousState = _states[index];
_set[index] = key;
_states[index] = FULL;
_values[index] = value;
if (isNewMapping) {
postInsertHook( previousState == FREE );
}
return previous;
}
/** {@inheritDoc} */
public void putAll( Map<? extends Short, ? extends Byte> map ) {
ensureCapacity( map.size() );
// could optimize this for cases when map instanceof THashMap
for ( Map.Entry<? extends Short, ? extends Byte> entry : map.entrySet() ) {
this.put( entry.getKey().shortValue(), entry.getValue().byteValue() );
}
}
/** {@inheritDoc} */
public void putAll( TShortByteMap map ) {
ensureCapacity( map.size() );
TShortByteIterator iter = map.iterator();
while ( iter.hasNext() ) {
iter.advance();
this.put( iter.key(), iter.value() );
}
}
/** {@inheritDoc} */
public byte get( short key ) {
int index = index( key );
return index < 0 ? no_entry_value : _values[index];
}
/** {@inheritDoc} */
public void clear() {
super.clear();
Arrays.fill( _set, 0, _set.length, no_entry_key );
Arrays.fill( _values, 0, _values.length, no_entry_value );
Arrays.fill( _states, 0, _states.length, FREE );
}
/** {@inheritDoc} */
public boolean isEmpty() {
return 0 == _size;
}
/** {@inheritDoc} */
public byte remove( short key ) {
byte prev = no_entry_value;
int index = index( key );
if ( index >= 0 ) {
prev = _values[index];
removeAt( index ); // clear key,state; adjust size
}
return prev;
}
/** {@inheritDoc} */
protected void removeAt( int index ) {
_values[index] = no_entry_value;
super.removeAt( index ); // clear key, state; adjust size
}
/** {@inheritDoc} */
public TShortSet keySet() {
return new TKeyView();
}
/** {@inheritDoc} */
public short[] keys() {
short[] keys = new short[size()];
short[] k = _set;
byte[] states = _states;
for ( int i = k.length, j = 0; i-- > 0; ) {
if ( states[i] == FULL ) {
keys[j++] = k[i];
}
}
return keys;
}
/** {@inheritDoc} */
public short[] keys( short[] array ) {
int size = size();
if ( array.length < size ) {
array = new short[size];
}
short[] keys = _set;
byte[] states = _states;
for ( int i = keys.length, j = 0; i-- > 0; ) {
if ( states[i] == FULL ) {
array[j++] = keys[i];
}
}
return array;
}
/** {@inheritDoc} */
public TByteCollection valueCollection() {
return new TValueView();
}
/** {@inheritDoc} */
public byte[] values() {
byte[] vals = new byte[size()];
byte[] v = _values;
byte[] states = _states;
for ( int i = v.length, j = 0; i-- > 0; ) {
if ( states[i] == FULL ) {
vals[j++] = v[i];
}
}
return vals;
}
/** {@inheritDoc} */
public byte[] values( byte[] array ) {
int size = size();
if ( array.length < size ) {
array = new byte[size];
}
byte[] v = _values;
byte[] states = _states;
for ( int i = v.length, j = 0; i-- > 0; ) {
if ( states[i] == FULL ) {
array[j++] = v[i];
}
}
return array;
}
/** {@inheritDoc} */
public boolean containsValue( byte val ) {
byte[] states = _states;
byte[] vals = _values;
for ( int i = vals.length; i-- > 0; ) {
if ( states[i] == FULL && val == vals[i] ) {
return true;
}
}
return false;
}
/** {@inheritDoc} */
public boolean containsKey( short key ) {
return contains( key );
}
/** {@inheritDoc} */
public TShortByteIterator iterator() {
return new TShortByteHashIterator( this );
}
/** {@inheritDoc} */
public boolean forEachKey( TShortProcedure procedure ) {
return forEach( procedure );
}
/** {@inheritDoc} */
public boolean forEachValue( TByteProcedure procedure ) {
byte[] states = _states;
byte[] values = _values;
for ( int i = values.length; i-- > 0; ) {
if ( states[i] == FULL && ! procedure.execute( values[i] ) ) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean forEachEntry( TShortByteProcedure procedure ) {
byte[] states = _states;
short[] keys = _set;
byte[] values = _values;
for ( int i = keys.length; i-- > 0; ) {
if ( states[i] == FULL && ! procedure.execute( keys[i], values[i] ) ) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public void transformValues( TByteFunction function ) {
byte[] states = _states;
byte[] values = _values;
for ( int i = values.length; i-- > 0; ) {
if ( states[i] == FULL ) {
values[i] = function.execute( values[i] );
}
}
}
/** {@inheritDoc} */
public boolean retainEntries( TShortByteProcedure procedure ) {
boolean modified = false;
byte[] states = _states;
short[] keys = _set;
byte[] values = _values;
// Temporarily disable compaction. This is a fix for bug #1738760
tempDisableAutoCompaction();
try {
for ( int i = keys.length; i-- > 0; ) {
if ( states[i] == FULL && ! procedure.execute( keys[i], values[i] ) ) {
removeAt( i );
modified = true;
}
}
}
finally {
reenableAutoCompaction( true );
}
return modified;
}
/** {@inheritDoc} */
public boolean increment( short key ) {
return adjustValue( key, ( byte ) 1 );
}
/** {@inheritDoc} */
public boolean adjustValue( short key, byte amount ) {
int index = index( key );
if (index < 0) {
return false;
} else {
_values[index] += amount;
return true;
}
}
/** {@inheritDoc} */
public byte adjustOrPutValue( short key, byte adjust_amount, byte put_amount ) {
int index = insertionIndex( key );
final boolean isNewMapping;
final byte newValue;
if ( index < 0 ) {
index = -index -1;
newValue = ( _values[index] += adjust_amount );
isNewMapping = false;
} else {
newValue = ( _values[index] = put_amount );
isNewMapping = true;
}
byte previousState = _states[index];
_set[index] = key;
_states[index] = FULL;
if ( isNewMapping ) {
postInsertHook(previousState == FREE);
}
return newValue;
}
/** a view onto the keys of the map. */
protected class TKeyView implements TShortSet {
/** {@inheritDoc} */
public TShortIterator iterator() {
return new TShortByteKeyHashIterator( TShortByteHashMap.this );
}
/** {@inheritDoc} */
public short getNoEntryValue() {
return no_entry_key;
}
/** {@inheritDoc} */
public int size() {
return _size;
}
/** {@inheritDoc} */
public boolean isEmpty() {
return 0 == _size;
}
/** {@inheritDoc} */
public boolean contains( short entry ) {
return TShortByteHashMap.this.contains( entry );
}
/** {@inheritDoc} */
public short[] toArray() {
return TShortByteHashMap.this.keys();
}
/** {@inheritDoc} */
public short[] toArray( short[] dest ) {
return TShortByteHashMap.this.keys( dest );
}
/**
* Unsupported when operating upon a Key Set view of a TShortByteMap
* <p/>
* {@inheritDoc}
*/
public boolean add( short entry ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
public boolean remove( short entry ) {
return no_entry_value != TShortByteHashMap.this.remove( entry );
}
/** {@inheritDoc} */
public boolean containsAll( Collection<?> collection ) {
for ( Object element : collection ) {
if ( element instanceof Short ) {
short ele = ( ( Short ) element ).shortValue();
if ( ! TShortByteHashMap.this.containsKey( ele ) ) {
return false;
}
} else {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean containsAll( TShortCollection collection ) {
TShortIterator iter = collection.iterator();
while ( iter.hasNext() ) {
if ( ! TShortByteHashMap.this.containsKey( iter.next() ) ) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean containsAll( short[] array ) {
for ( short element : array ) {
if ( ! TShortByteHashMap.this.contains( element ) ) {
return false;
}
}
return true;
}
/**
* Unsupported when operating upon a Key Set view of a TShortByteMap
* <p/>
* {@inheritDoc}
*/
public boolean addAll( Collection<? extends Short> collection ) {
throw new UnsupportedOperationException();
}
/**
* Unsupported when operating upon a Key Set view of a TShortByteMap
* <p/>
* {@inheritDoc}
*/
public boolean addAll( TShortCollection collection ) {
throw new UnsupportedOperationException();
}
/**
* Unsupported when operating upon a Key Set view of a TShortByteMap
* <p/>
* {@inheritDoc}
*/
public boolean addAll( short[] array ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
@SuppressWarnings({"SuspiciousMethodCalls"})
public boolean retainAll( Collection<?> collection ) {
boolean modified = false;
TShortIterator iter = iterator();
while ( iter.hasNext() ) {
if ( ! collection.contains( Short.valueOf ( iter.next() ) ) ) {
iter.remove();
modified = true;
}
}
return modified;
}
/** {@inheritDoc} */
public boolean retainAll( TShortCollection collection ) {
if ( this == collection ) {
return false;
}
boolean modified = false;
TShortIterator iter = iterator();
while ( iter.hasNext() ) {
if ( ! collection.contains( iter.next() ) ) {
iter.remove();
modified = true;
}
}
return modified;
}
/** {@inheritDoc} */
public boolean retainAll( short[] array ) {
boolean changed = false;
Arrays.sort( array );
short[] set = _set;
byte[] states = _states;
for ( int i = set.length; i-- > 0; ) {
if ( states[i] == FULL && ( Arrays.binarySearch( array, set[i] ) < 0) ) {
removeAt( i );
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( Collection<?> collection ) {
boolean changed = false;
for ( Object element : collection ) {
if ( element instanceof Short ) {
short c = ( ( Short ) element ).shortValue();
if ( remove( c ) ) {
changed = true;
}
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( TShortCollection collection ) {
if ( this == collection ) {
clear();
return true;
}
boolean changed = false;
TShortIterator iter = collection.iterator();
while ( iter.hasNext() ) {
short element = iter.next();
if ( remove( element ) ) {
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( short[] array ) {
boolean changed = false;
for ( int i = array.length; i-- > 0; ) {
if ( remove( array[i] ) ) {
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public void clear() {
TShortByteHashMap.this.clear();
}
/** {@inheritDoc} */
public boolean forEach( TShortProcedure procedure ) {
return TShortByteHashMap.this.forEachKey( procedure );
}
@Override
public boolean equals( Object other ) {
if (! (other instanceof TShortSet)) {
return false;
}
final TShortSet that = ( TShortSet ) other;
if ( that.size() != this.size() ) {
return false;
}
for ( int i = _states.length; i-- > 0; ) {
if ( _states[i] == FULL ) {
if ( ! that.contains( _set[i] ) ) {
return false;
}
}
}
return true;
}
@Override
public int hashCode() {
int hashcode = 0;
for ( int i = _states.length; i-- > 0; ) {
if ( _states[i] == FULL ) {
hashcode += HashFunctions.hash( _set[i] );
}
}
return hashcode;
}
@Override
public String toString() {
final StringBuilder buf = new StringBuilder( "{" );
forEachKey( new TShortProcedure() {
private boolean first = true;
public boolean execute( short key ) {
if ( first ) {
first = false;
} else {
buf.append( ", " );
}
buf.append( key );
return true;
}
} );
buf.append( "}" );
return buf.toString();
}
}
/** a view onto the values of the map. */
protected class TValueView implements TByteCollection {
/** {@inheritDoc} */
public TByteIterator iterator() {
return new TShortByteValueHashIterator( TShortByteHashMap.this );
}
/** {@inheritDoc} */
public byte getNoEntryValue() {
return no_entry_value;
}
/** {@inheritDoc} */
public int size() {
return _size;
}
/** {@inheritDoc} */
public boolean isEmpty() {
return 0 == _size;
}
/** {@inheritDoc} */
public boolean contains( byte entry ) {
return TShortByteHashMap.this.containsValue( entry );
}
/** {@inheritDoc} */
public byte[] toArray() {
return TShortByteHashMap.this.values();
}
/** {@inheritDoc} */
public byte[] toArray( byte[] dest ) {
return TShortByteHashMap.this.values( dest );
}
public boolean add( byte entry ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
public boolean remove( byte entry ) {
byte[] values = _values;
short[] set = _set;
for ( int i = values.length; i-- > 0; ) {
if ( ( set[i] != FREE && set[i] != REMOVED ) && entry == values[i] ) {
removeAt( i );
return true;
}
}
return false;
}
/** {@inheritDoc} */
public boolean containsAll( Collection<?> collection ) {
for ( Object element : collection ) {
if ( element instanceof Byte ) {
byte ele = ( ( Byte ) element ).byteValue();
if ( ! TShortByteHashMap.this.containsValue( ele ) ) {
return false;
}
} else {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean containsAll( TByteCollection collection ) {
TByteIterator iter = collection.iterator();
while ( iter.hasNext() ) {
if ( ! TShortByteHashMap.this.containsValue( iter.next() ) ) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean containsAll( byte[] array ) {
for ( byte element : array ) {
if ( ! TShortByteHashMap.this.containsValue( element ) ) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
public boolean addAll( Collection<? extends Byte> collection ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
public boolean addAll( TByteCollection collection ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
public boolean addAll( byte[] array ) {
throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
@SuppressWarnings({"SuspiciousMethodCalls"})
public boolean retainAll( Collection<?> collection ) {
boolean modified = false;
TByteIterator iter = iterator();
while ( iter.hasNext() ) {
if ( ! collection.contains( Byte.valueOf ( iter.next() ) ) ) {
iter.remove();
modified = true;
}
}
return modified;
}
/** {@inheritDoc} */
public boolean retainAll( TByteCollection collection ) {
if ( this == collection ) {
return false;
}
boolean modified = false;
TByteIterator iter = iterator();
while ( iter.hasNext() ) {
if ( ! collection.contains( iter.next() ) ) {
iter.remove();
modified = true;
}
}
return modified;
}
/** {@inheritDoc} */
public boolean retainAll( byte[] array ) {
boolean changed = false;
Arrays.sort( array );
byte[] values = _values;
byte[] states = _states;
for ( int i = values.length; i-- > 0; ) {
if ( states[i] == FULL && ( Arrays.binarySearch( array, values[i] ) < 0) ) {
removeAt( i );
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( Collection<?> collection ) {
boolean changed = false;
for ( Object element : collection ) {
if ( element instanceof Byte ) {
byte c = ( ( Byte ) element ).byteValue();
if ( remove( c ) ) {
changed = true;
}
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( TByteCollection collection ) {
if ( this == collection ) {
clear();
return true;
}
boolean changed = false;
TByteIterator iter = collection.iterator();
while ( iter.hasNext() ) {
byte element = iter.next();
if ( remove( element ) ) {
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public boolean removeAll( byte[] array ) {
boolean changed = false;
for ( int i = array.length; i-- > 0; ) {
if ( remove( array[i] ) ) {
changed = true;
}
}
return changed;
}
/** {@inheritDoc} */
public void clear() {
TShortByteHashMap.this.clear();
}
/** {@inheritDoc} */
public boolean forEach( TByteProcedure procedure ) {
return TShortByteHashMap.this.forEachValue( procedure );
}
/** {@inheritDoc} */
@Override
public String toString() {
final StringBuilder buf = new StringBuilder( "{" );
forEachValue( new TByteProcedure() {
private boolean first = true;
public boolean execute( byte value ) {
if ( first ) {
first = false;
} else {
buf.append( ", " );
}
buf.append( value );
return true;
}
} );
buf.append( "}" );
return buf.toString();
}
}
class TShortByteKeyHashIterator extends THashPrimitiveIterator implements TShortIterator {
/**
* Creates an iterator over the specified map
*
* @param hash the <tt>TPrimitiveHash</tt> we will be iterating over.
*/
TShortByteKeyHashIterator( TPrimitiveHash hash ) {
super( hash );
}
/** {@inheritDoc} */
public short next() {
moveToNextIndex();
return _set[_index];
}
/** @{inheritDoc} */
public void remove() {
if ( _expectedSize != _hash.size() ) {
throw new ConcurrentModificationException();
}
// Disable auto compaction during the remove. This is a workaround for bug 1642768.
try {
_hash.tempDisableAutoCompaction();
TShortByteHashMap.this.removeAt( _index );
}
finally {
_hash.reenableAutoCompaction( false );
}
_expectedSize--;
}
}
class TShortByteValueHashIterator extends THashPrimitiveIterator implements TByteIterator {
/**
* Creates an iterator over the specified map
*
* @param hash the <tt>TPrimitiveHash</tt> we will be iterating over.
*/
TShortByteValueHashIterator( TPrimitiveHash hash ) {
super( hash );
}
/** {@inheritDoc} */
public byte next() {
moveToNextIndex();
return _values[_index];
}
/** @{inheritDoc} */
public void remove() {
if ( _expectedSize != _hash.size() ) {
throw new ConcurrentModificationException();
}
// Disable auto compaction during the remove. This is a workaround for bug 1642768.
try {
_hash.tempDisableAutoCompaction();
TShortByteHashMap.this.removeAt( _index );
}
finally {
_hash.reenableAutoCompaction( false );
}
_expectedSize--;
}
}
class TShortByteHashIterator extends THashPrimitiveIterator implements TShortByteIterator {
/**
* Creates an iterator over the specified map
*
* @param map the <tt>TShortByteHashMap</tt> we will be iterating over.
*/
TShortByteHashIterator( TShortByteHashMap map ) {
super( map );
}
/** {@inheritDoc} */
public void advance() {
moveToNextIndex();
}
/** {@inheritDoc} */
public short key() {
return _set[_index];
}
/** {@inheritDoc} */
public byte value() {
return _values[_index];
}
/** {@inheritDoc} */
public byte setValue( byte val ) {
byte old = value();
_values[_index] = val;
return old;
}
/** @{inheritDoc} */
public void remove() {
if ( _expectedSize != _hash.size() ) {
throw new ConcurrentModificationException();
}
// Disable auto compaction during the remove. This is a workaround for bug 1642768.
try {
_hash.tempDisableAutoCompaction();
TShortByteHashMap.this.removeAt( _index );
}
finally {
_hash.reenableAutoCompaction( false );
}
_expectedSize--;
}
}
/** {@inheritDoc} */
@Override
public boolean equals( Object other ) {
if ( ! ( other instanceof TShortByteMap ) ) {
return false;
}
TShortByteMap that = ( TShortByteMap ) other;
if ( that.size() != this.size() ) {
return false;
}
byte[] values = _values;
byte[] states = _states;
byte this_no_entry_value = getNoEntryValue();
byte that_no_entry_value = that.getNoEntryValue();
for ( int i = values.length; i-- > 0; ) {
if ( states[i] == FULL ) {
short key = _set[i];
byte that_value = that.get( key );
byte this_value = values[i];
if ( ( this_value != that_value ) &&
( this_value != this_no_entry_value ) &&
( that_value != that_no_entry_value ) ) {
return false;
}
}
}
return true;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
int hashcode = 0;
byte[] states = _states;
for ( int i = _values.length; i-- > 0; ) {
if ( states[i] == FULL ) {
hashcode += HashFunctions.hash( _set[i] ) ^
HashFunctions.hash( _values[i] );
}
}
return hashcode;
}
/** {@inheritDoc} */
@Override
public String toString() {
final StringBuilder buf = new StringBuilder( "{" );
forEachEntry( new TShortByteProcedure() {
private boolean first = true;
public boolean execute( short key, byte value ) {
if ( first ) first = false;
else buf.append( ", " );
buf.append(key);
buf.append("=");
buf.append(value);
return true;
}
});
buf.append( "}" );
return buf.toString();
}
/** {@inheritDoc} */
public void writeExternal(ObjectOutput out) throws IOException {
// VERSION
out.writeByte( 0 );
// SUPER
super.writeExternal( out );
// NUMBER OF ENTRIES
out.writeInt( _size );
// ENTRIES
for ( int i = _states.length; i-- > 0; ) {
if ( _states[i] == FULL ) {
out.writeShort( _set[i] );
out.writeByte( _values[i] );
}
}
}
/** {@inheritDoc} */
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// VERSION
in.readByte();
// SUPER
super.readExternal( in );
// NUMBER OF ENTRIES
int size = in.readInt();
setUp( size );
// ENTRIES
while (size-- > 0) {
short key = in.readShort();
byte val = in.readByte();
put(key, val);
}
}
} // TShortByteHashMap