/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.core.hash;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections.map.AbstractHashedMap;
import org.pentaho.di.core.exception.KettleValueException;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
public class ByteArrayHashMap extends AbstractHashedMap {
private RowMetaInterface keyMeta;
/**
* Constructs an empty <tt>ByteArrayHashMap</tt> with the specified initial capacity and load factor.
*
* @param initialCapacity
* the initial capacity
* @param loadFactor
* the load factor
* @throws IllegalArgumentException
* if the initial capacity is negative or the load factor is nonpositive
*/
public ByteArrayHashMap( int initialCapacity, float loadFactor, RowMetaInterface keyMeta ) {
super( initialCapacity, loadFactor );
this.keyMeta = keyMeta;
}
@Override
protected boolean isEqualKey( Object key1, Object key2 ) {
return equalsByteArray( (byte[]) key1, (byte[]) key2 );
}
@Override
protected boolean isEqualValue( Object value1, Object value2 ) {
return equalsByteArray( (byte[]) value1, (byte[]) value2 );
}
public final boolean equalsByteArray( byte[] value, byte[] cmpValue ) {
if ( value.length == cmpValue.length ) {
for ( int i = 0; i < value.length; i++ ) {
if ( value[i] != cmpValue[i] ) {
return false;
}
}
return true;
}
return false;
}
/**
* Constructs an empty <tt>ByteArrayHashMap</tt> with the specified initial capacity and the default load factor
* (0.75).
*
* @param initialCapacity
* the initial capacity.
* @throws IllegalArgumentException
* if the initial capacity is negative.
*/
public ByteArrayHashMap( int initialCapacity, RowMetaInterface keyMeta ) {
this( initialCapacity, DEFAULT_LOAD_FACTOR, keyMeta );
}
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity (16) and the default load factor (0.75).
*/
public ByteArrayHashMap( RowMetaInterface keyMeta ) {
this( DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, keyMeta );
}
/**
* Returns the entry to which the specified key is "mapped", or, in other words, if this index contains an
* entry that is equal to the given key, or {@code null} if this is not the case.
*
* <p>
* More formally, if this index contains an entry {@code e} such that {@code key.equals(e))}, then this method returns
* {@code e}; otherwise it returns {@code null}. (There can be at most one such entry.)
*
* @param key
* The key to look up.
* @throws KettleValueException
* in case of a value conversion error
*
* @see #put(Object)
* @see #insert(Object)
*/
public byte[] get( byte[] key ) {
return (byte[]) super.get( key );
}
public void put( byte[] key, byte[] value ) {
super.put( key, value );
}
@Override
protected int hash( Object key ) {
byte[] rowKey = (byte[]) key;
try {
return keyMeta.hashCode( RowMeta.getRow( keyMeta, rowKey ) );
} catch ( KettleValueException ex ) {
throw new IllegalArgumentException( ex );
}
}
@SuppressWarnings( "unchecked" )
public List<byte[]> getKeys() {
List<byte[]> rtn = new ArrayList<byte[]>( this.size() );
Set<byte[]> kSet = this.keySet();
for ( Iterator<byte[]> it = kSet.iterator(); it.hasNext(); ) {
rtn.add( it.next() );
}
return rtn;
}
}