/* * `gnu.iou' * Copyright (C) 2006 John Pritchard. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program 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 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.iou ; /** * <p> Hasharray mapping from int primitive to int primitive. </p> * * @see intmap * @see hasharray * * @author jdp */ public class intint extends hasharray { public long[] keys = null; public int[] vals = null; public intint(int initial, float load){ super(initial,load); this.keys = new long[this.table.grow]; this.vals = new int[this.table.grow]; } public intint(int initial){ super(initial); this.keys = new long[this.table.grow]; this.vals = new int[this.table.grow]; } public intint(){ super(); this.keys = new long[this.table.grow]; this.vals = new int[this.table.grow]; } public int[] keyary(){ return this._keyary(); } protected final int[] _keyary(){ int many = this.count; if ( 0 < many){ long[] keys = this.keys; int[] ret = new int[many]; for (int idx = 0; idx < many; idx++) ret[idx] = (int)(keys[idx] & 0xffffffffL); return ret; } else return null; } public int[] valary(){ return this._valary(); } protected final int[] _valary(){ int many = this.count; if ( 0 < many){ int[] vals = this.vals; int[] ret = new int[many]; System.arraycopy(vals,0,ret,0,many); return ret; } else return null; } public long lastKey(){ return this._lastKey(); } protected final long _lastKey(){ int idx = (this.count-1); if (-1 < idx) return this.keys[idx]; else return KL_NIL; } public int lastValue(){ return this._lastValue(); } protected final int _lastValue(){ int idx = (this.count-1); if (-1 < idx) return this.vals[idx]; else return ZED; } public void lastValue( int val){ this._lastValue(val); } protected final void _lastValue( int val){ int idx = (this.count-1); if (-1 < idx) this.vals[idx] = val; } public java.util.Enumeration keys(){ return this._keys(); } protected final java.util.Enumeration _keys(){ return new Enumerator3(this.keys, this.count); } public java.util.Enumeration elements(){ return this._elements(); } protected final java.util.Enumeration _elements(){ return new Enumerator2(this.vals, this.count); } public boolean containsValue(int value){ return this.contains(value); } public boolean _containsValue(int value){ return this._contains(value); } public boolean contains(int value){ return this._contains(value); } protected final boolean _contains(int value){ int sval, vals[] = this.vals; for (int ti = (this.count-1) ; 0 <= ti; ti--){ sval = vals[ti]; if (value == sval) return true; } return false; } public boolean containsKey(int key){ return this._containsKey(key); } protected final boolean _containsKey(int key){ return (null != this._lookup(key)); } public int indexOf(int key){ return this._indexOf(key); } protected final int _indexOf(int key){ Index.Entry e = this._lookup(key); if (null == e) return -1; else return e.aryix; } public int indexOf( int key, int fromIdx){ return this._indexOf(key,fromIdx); } protected final int _indexOf( int key, int fromIdx){ long lkey = key; int many = this.count; long keys[] = this.keys; if (-1 < fromIdx && fromIdx < many){ for ( int idx = fromIdx; idx < many; idx++){ if (lkey == keys[idx]) return idx; } } return -1; } public int lastIndexOf( int key){ return this._lastIndexOf(key); } protected final int _lastIndexOf( int key){ if (KL_NIL == key) return -1; else return this.lastIndexOf(key,(this.count-1)); } public int lastIndexOf( int key, int fromIdx){ return this._lastIndexOf(key,fromIdx); } protected final int _lastIndexOf( int key, int fromIdx){ long lkey = key; int many = this.count; long keys[] = this.keys; if (-1 < fromIdx && fromIdx < many){ for ( int idx = fromIdx; -1 < idx; idx--){ if (lkey == keys[idx]) return idx; } } return -1; } public int indexOfValue( int val){ return this.indexOfValue(val,0); } public int indexOfValue( int val, int fromIdx){ return this._indexOfValue(val,fromIdx); } protected final int _indexOfValue( int val, int fromIdx){ int many = this.count; int vals[] = this.vals; if (-1 < fromIdx && fromIdx < many){ for ( int idx = fromIdx; idx < many; idx++){ if (val == vals[idx]) return idx; } } return -1; } public int lastIndexOfValue( int val){ return this.lastIndexOfValue(val,(this.count-1)); } public int lastIndexOfValue( int val, int fromIdx){ return this._lastIndexOfValue(val,fromIdx); } protected final int _lastIndexOfValue( int val, int fromIdx){ int many = this.count; int vals[] = this.vals; if (-1 < fromIdx && fromIdx < many){ for ( int idx = fromIdx; -1 < idx; idx--){ if (val == vals[idx]) return idx; } } return -1; } public Object get(Object key){ return this._get(key); } protected final Object _get(Object key){ if (null == key) return null; else if (!(key instanceof java.lang.Number)) throw new IllegalArgumentException("key "+key.getClass()); else { int kei = ((java.lang.Number)key).intValue(); int idx = this._indexOf(kei); if (-1 < idx && idx < this.count){ int re = this.vals[idx]; return new java.lang.Integer(re); } else return null; } } public int get(int key){ return this._get(key); } protected final int _get(int key){ int idx = this._indexOf(key); if (-1 < idx && idx < this.count) return this.vals[idx]; else return ZED; } public Object keyO(int idx){ return this._keyO(idx); } protected final Object _keyO(int idx){ if (-1 < idx && idx < this.count){ long lkey = this.keys[idx]; if (KL_NIL == lkey) return null; else return new java.lang.Integer( (int)lkey); } else return null; } public int key(int idx){ return this._key(idx); } protected final int _key(int idx){ if (-1 < idx && idx < this.count){ long lkey = this.keys[idx]; if (KL_NIL == lkey) return ZED; else return (int)lkey; } else return ZED; } public long keyL(int idx){ return this._keyL(idx); } protected final long _keyL(int idx){ if (-1 < idx && idx < this.count) return this.keys[idx]; else return KL_NIL; } public int value(int idx){ return this._value(idx); } protected final int _value(int idx){ if (-1 < idx && idx < this.count) return this.vals[idx]; else return ZED; } public int value(int idx, int value){ return this._value(idx,value); } protected final int _value(int idx, int value){ if (-1 < idx && idx < this.count) return (this.vals[idx] = value); else return ZED; } /** * Replace the keyed value */ public Object put(Object key, Object value){ return this._put(key,value); } protected final Object _put(Object key, Object value){ if (null == key) return null; else if (!(key instanceof java.lang.Number)) throw new IllegalArgumentException("key "+key.getClass()); else if (!(value instanceof java.lang.Number)) throw new IllegalArgumentException("value "+value.getClass()); else { int kei = ((java.lang.Number)key).intValue(); int val = ((java.lang.Number)value).intValue(); Index.Entry ent = this.table.store(this,kei); int aryix = ent.aryix; if (Index.Entry.XINIT == aryix){ ent.aryix = this._vadd_(kei,val); return null;/*(new)*/ } else { int old = this.vals[aryix]; this.vals[aryix] = val; return new java.lang.Integer(old); } } } public int put(int key, int value){ return this._put(key,value); } protected final int _put(int key, int value){ Index.Entry ent = this.table.store(this,key); int aryix = ent.aryix; if (Index.Entry.XINIT == aryix){ ent.aryix = this._vadd_(key,value); return ZED;/*(new)*/ } else { int old = this.vals[aryix]; this.vals[aryix] = value; return old; } } /** * Add a potentially duplicate key. It enters the index (get- put * "key" interface) when it is unique, or as a duplicate when the * key (former) is removed. */ public int add( int key, int val){ return this._add(key,val); } protected final int _add( int key, int val){ Index.Entry ent = this.table.add(this,key); int aryix = ent.aryix; if (Index.Entry.XINIT == aryix){ ent.aryix = this._vadd_(key,val); return ent.aryix; } else { this.vals[aryix] = val; return aryix; } } /** * <p> Insert the argument pair. If the key has been indexed * before, the new key is inserted into the index before it.</p> */ public int insert( int idx, int key, int val){ return this._insert(idx,key,val); } protected final int _insert( int idx, int key, int val){ if (0 > idx) return this.add(key,val); else { long[] keys = this.keys; int[] vals = this.vals; int len = keys.length; long[] kcopier = new long[len+1];// simple aglo: always grow by one int[] vcopier = new int[len+1];// if ( 0 == idx){ System.arraycopy(keys,0,kcopier,1,len); System.arraycopy(vals,0,vcopier,1,len); kcopier[idx] = key; vcopier[idx] = val; } else if (idx == (len-1)){ System.arraycopy(keys,0,kcopier,0,len); System.arraycopy(vals,0,vcopier,0,len); kcopier[idx] = key; vcopier[idx] = val; } else { System.arraycopy(keys,0,kcopier,0,idx); System.arraycopy(vals,0,vcopier,0,idx); System.arraycopy(keys,idx,kcopier,idx+1,(len-idx));//copied (many=idx) above System.arraycopy(vals,idx,vcopier,idx+1,(len-idx)); kcopier[idx] = key; vcopier[idx] = val; } this.keys = kcopier; this.vals = vcopier; this.count += 1; Index.Entry ent = this.table.insert(this,idx,key); if (Index.Entry.XINIT == ent.aryix){ ent.aryix = idx; return idx; } else throw new IllegalStateException("BBBUGGGG"); } } /** * <p> Replace the key- value pair at key- value index 'idx' with * the argument pair.</p> */ public int replace( int idx, int nkey, int nval){ return this._replace(idx,nkey,nval); } protected final int _replace( int idx, int nkey, int nval){ if (0 > idx || idx >= this.count) return this.add(nkey,nval); else { long okey = this.keys[idx]; if (okey == nkey){ this.vals[idx] = nval; return idx; } else { Index.Entry ent = this.table.replace(this,idx,nkey,okey); ent.aryix = idx; this.keys[idx] = nkey; this.vals[idx] = nval; return idx; } } } /** * <p> Append new key- value pair. If the key has been indexed * before, the new key is appended into the index after it. </p> */ public int append( int nkey, int nval){ return this._append(nkey,nval); } protected final int _append( int nkey, int nval){ int idx = this._indexOf(nkey); if (0 > idx) return this.add(nkey,nval); else { idx = this._vadd_(nkey,nval); // Index.Entry ent = this.table.append(this,nkey); ent.aryix = idx; return idx; } } /** * Add to data vectors, no index activity. Manage optimistic * vectors. */ protected final int _vadd_ ( int key, int val){ int idx = this.count, len = this.keys.length; if ( idx >= (len-1)){ // grow rate int grow = (len/3); if (this.table.grow > grow) grow = this.table.grow; // int nlen = len+(grow); // grow keys long[] k_copier = new long[nlen]; System.arraycopy(keys,0,k_copier,0,len); keys = k_copier; // grow vals int[] v_copier = new int[nlen]; System.arraycopy(vals,0,v_copier,0,len); vals = v_copier; } this.keys[idx] = key; this.vals[idx] = val; this.count += 1; return idx; } /** * Drop slot by index */ public int drop( int idx){ return this._drop(idx); } protected final int _drop( int idx){ if (0 > idx || idx >= this.count) return ZED; else { long key = this.keys[idx]; if (KL_NIL == key) return ZED; else { int ikey = (int)key; int kidx = this._indexOf(ikey); if ( kidx == idx){ /* * (this.keys[idx]) is the first indexed key */ return this._remove(ikey); } else { if (-1 < kidx) /* * (this.keys[idx]) is not the first indexed key */ this.table.remove(this,idx); int old = this.vals[idx]; shift(this.keys,idx); shift(this.vals,idx); this.count--; return old; } } } } public Object remove( Object key){ return this._remove(key); } protected final Object _remove( Object key){ if (null == key) return null; else if (!(key instanceof java.lang.Number)) throw new java.lang.IllegalArgumentException("key "+key.getClass()); else { int kei = ((java.lang.Number)key).intValue(); if (-1 < this.indexOf(kei)){ int re = this.remove(kei); return new java.lang.Integer(re); } else return null; } } /** * Remove key and value, index any latter identical key, truncate * data arrays (keys and vals), scan index table and decrement * pointer indeces for truncated data arrays. */ public int remove( int key){ return this._remove(key); } protected final int _remove( int key){ Index.Entry dropped = this.table.remove(this,key); if (null != dropped){ int aryix = dropped.aryix; if (-1 < aryix){ long keys[] = this.keys; int vals[] = this.vals; int ret = vals[aryix]; keys[aryix] = KL_NIL; vals[aryix] = ZED; shift(keys,aryix); shift(vals,aryix); this.count--; return ret; } } return ZED; } public void clear(){ this._clear(); } protected final void _clear(){ this.table.clear(this); long[] keys = this.keys; int[] vals = this.vals; for (int index = 0, count = this.count; index < count; index++){ keys[index] = KL_NIL; vals[index] = ZED; } this.count = 0; } public final intint cloneIntint(){ intint t = (intint)super.cloneHasharray(); t.keys = (long[])this.keys.clone(); t.vals = (int[])this.vals.clone(); return t; } }