package dictionary; import arraylist.ArrayIndexList; import arraylist.IndexList; import exceptions.HashExceptionKey; import exceptions.InvalidEntryException; import position.NodePositionList; import priorityqueue.Entry; import exceptions.InvalidKeyException; import java.util.Iterator; /** * Created with MONSTER. * User: xgiovio * Date: 11/05/2014 * Time: 19:28 */ //Complete implementation by xgiovio //Collisions resolved via chaining with LogFile.java public class ChainingHashTable implements Dictionary { IndexList> table = null; LogFile AVAIBLE = null; int avaible_slots = 0; int elements = 0; int p = 0; int scale = 0; int shift = 0; public ChainingHashTable(int in_p, int in_size){ table = new ArrayIndexList>(in_size); AVAIBLE = new LogFile(); p = in_p; java.util.Random rand = new java.util.Random(); scale = rand.nextInt(p-1) + 1; shift = rand.nextInt(p); for (int i= 0 ; i< in_size ;i++){ table.add(i,AVAIBLE); avaible_slots ++; } } public ChainingHashTable(int in_size){ this(109345121,in_size); } public ChainingHashTable(){ this(109345121,100); } public float load_factor () throws InvalidKeyException{ float ret = (size() / (float)raw_size()); if ( ret >= 0.9 ) { reformat(); return load_factor(); } return ret; } public int raw_size (){ return table.size(); } @Override public int size() { return elements; } @Override public boolean isEmpty() { return (size() == 0); } protected int hash ( K key){ return (int) ((Math.abs(key.hashCode()*scale + shift) % p) % raw_size()); } @Override public Entry find(K key) throws InvalidKeyException { checkKey(key); int h = hash(key); if (table.get(h) == AVAIBLE) return null; LogFile n = table.get(h); return n.find(key); } @Override public Iterable> findAll(K key) throws InvalidKeyException { checkKey(key); int h = hash(key); if (table.get(h) == AVAIBLE) return null; LogFile n = table.get(h); return n.entries(); } @Override public Entry insert(K key, V value) throws InvalidKeyException { checkKey(key); if (load_factor() >= 0.9 ) reformat(); int h = hash(key); if (table.get(h) == AVAIBLE) { LogFile n = new LogFile(); table.set(h,n); avaible_slots--; elements++; return n.insert(key,value); } else { LogFile n = table.get(h); elements++; return n.insert(key,value); } } protected Entry insert_refactor(Entry in_e) throws InvalidKeyException { // in_e not checked because used internally int h = hash(in_e.getKey()); if (table.get(h) == AVAIBLE) { LogFile n = new LogFile(); table.set(h,n); avaible_slots--; elements++; return n.insert(in_e); } else { LogFile n = table.get(h); elements++; return n.insert(in_e); } } @Override public Entry remove(Entry e) throws InvalidEntryException { if (e == null) throw new InvalidEntryException(); int h = hash(e.getKey()); if (table.get(h) == AVAIBLE) throw new InvalidEntryException(); LogFile n = table.get(h); Entry t = n.remove(e); elements--; if (n.size() == 0){ table.set(h,AVAIBLE); avaible_slots++; } return t; } @Override public Iterable> entries() { NodePositionList> ret = new NodePositionList>(); for (int i = 0 ; i< raw_size() ;i++){ if (table.get(i) != AVAIBLE){ Iterator> local_it = table.get(i).entries().iterator(); for (;local_it.hasNext();){ ret.addLast(local_it.next()); } } } return ret; } protected void checkKey(K key) throws InvalidKeyException { if (key == null ) throw new InvalidKeyException("Invalid key"); } void reformat () throws InvalidKeyException{ Iterable> ite = entries(); int new_size = raw_size() * 2; IndexList> table2 = new ArrayIndexList>(new_size); avaible_slots = 0; elements = 0; java.util.Random rand = new java.util.Random(); scale = rand.nextInt(p-1) + 1; // new hash scaling factor shift = rand.nextInt(p); //// new hash shifting factor for (int i= 0 ; i< (new_size) ;i++){ table2.add(i,AVAIBLE); } table = table2; for (Entry e : ite){ insert_refactor(e); } } public String toString() { Iterator> it = entries().iterator(); String to_return = ""; to_return = to_return + "["; for (;it.hasNext();){ Entry t = it.next(); if (it.hasNext()) { to_return+=(t.toString() + " , "); } else { to_return+=(t.toString()); } } return to_return+= "]"; } }