package dictionary; import arraylist.ArrayIndexList; import arraylist.IndexList; import exceptions.HashExceptionKey; import exceptions.InvalidEntryException; import position.NodePositionList; import priorityqueue.Entry; import priorityqueue.MyEntry; import java.security.InvalidKeyException; import java.util.Iterator; /** * Created with MONSTER. * User: xgiovio * Date: 11/05/2014 * Time: 19:28 */ public class HashDictionaryLinearProbing implements Dictionary { IndexList> table = null; Entry AVAIBLE = null; int avaible_slots = 0; int elements = 0; public HashDictionaryLinearProbing(Entry IN_AVAIBLE, int in_size){ table = new ArrayIndexList>(in_size); AVAIBLE = IN_AVAIBLE; for (int i= 0 ; i< in_size ;i++){ table.add(i,AVAIBLE); avaible_slots ++; } } public float load_factor () throws InvalidKeyException{ float ret = (size() / (float)raw_size()); if ( ret >= 0.5 ) { 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, int size){ if ( (key instanceof String) ) return com.xgiovio.hash.functions.hash_horner( (String)key ,size ); throw new HashExceptionKey(); } @Override public Entry find(K key) throws InvalidKeyException { checkKey(key); int h = hash(key, raw_size()); int count = 0; int i = 0; for (;count < raw_size();){ if (table.get(h+i) == AVAIBLE) return null; if (table.get(h+i).getKey().equals(key)) return table.get(h+i); i= (i + 1)% raw_size(); count++; } return null; } @Override public Iterable> findAll(K key) throws InvalidKeyException { checkKey(key); NodePositionList> to_return = new NodePositionList>(); int h = hash(key, raw_size()); int count = 0; int i = 0; for (;count < raw_size();){ if (table.get(h+i) == AVAIBLE) return to_return; if (table.get(h+i).getKey().equals(key)) to_return.addLast( table.get(h+i)); i= (i + 1)% raw_size(); count++; } return to_return; } @Override public Entry insert(K key, V value) throws InvalidKeyException { checkKey(key); if (load_factor() >= 0.5 ) reformat(); int h = hash(key,raw_size()); if (table.get(h) == AVAIBLE) { MyEntry n = new MyEntry(key,value); table.set(h,n); avaible_slots--; elements++; return n; } else { int i = 1; int count = 1; for ( ; count < raw_size() ;) { if (table.get(h + i) == AVAIBLE) { MyEntry n = new MyEntry(key, value); table.set(h + i, n); avaible_slots--; elements++; return n; } i = (i + 1) % raw_size(); count++; } return null; // non dovresti essere qui a causa del load factor } } @Override public Entry remove(Entry e) throws InvalidEntryException { if (e == null) throw new InvalidEntryException(); int h = hash(e.getKey(),raw_size()); if (table.get(h) == AVAIBLE) throw new InvalidEntryException(); if (table.get(h) == e) { Entry removed = table.get(h); table.remove(h); table.set(h,AVAIBLE); elements--; avaible_slots++; return removed; } int count = 1; for (int i = 1; count < raw_size() ; i = (i + 1) % raw_size()){ if (table.get(h + i) == AVAIBLE) throw new InvalidEntryException(); if (table.get(h + i) == e) { Entry removed = table.get(h + i); table.remove(h + i); table.set(h + i,AVAIBLE); elements--; avaible_slots++; return removed; } count++; } throw new InvalidEntryException(); } @Override public Iterable> entries() { NodePositionList> ret = new NodePositionList>(); for (int i = 0 ; i< raw_size() ;i++){ if (table.get(i) != AVAIBLE){ ret.addLast(table.get(i)); } } 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; for (int i= 0 ; i< (new_size) ;i++){ table2.add(i,AVAIBLE); } table = table2; for (Entry e : ite){ insert(e.getKey(),e.getValue()); } } 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+= "]"; } }