Skip to content

Instantly share code, notes, and snippets.

@allanx2000
Created December 24, 2015 17:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allanx2000/b38a02326760a59556de to your computer and use it in GitHub Desktop.
Save allanx2000/b38a02326760a59556de to your computer and use it in GitHub Desktop.
Tested. got OutOfMemory with 100k entries but not really optimized. Sequential crashes at 10k
public class LinearProbingHT<T1, T2> extends HashTable<T1, T2> {
private int size = 0;
private Object[] nodes;
public LinearProbingHT(int initSize) {
nodes = new Object[initSize];
}
private int getIndexFromHash(T1 key) {
int hash = key.hashCode();
hash = hash % nodes.length;
return hash;
}
private final double ALPHA_LEVEL = .5;
@Override
public void delete(T1 key) {
Integer idx = find(key);
if (idx != null) {
Node n = getNode(idx);
n.key = null;
n.value = null;
size--;
}
}
private Integer IndexForPut(T1 key) {
int hashIdx = getIndexFromHash(key);
if (isEmpty(hashIdx))
return hashIdx;
int idx = hashIdx + 1;
while (idx < nodes.length) {
if (!isEmpty(idx))
idx++;
else
return idx;
}
// Reached end
idx = 0;
while (!isEmpty(idx) && idx < hashIdx) {
idx++;
}
if (idx == hashIdx)
return null;
else
return idx;
}
private Integer find(T1 key) {
int hashIdx = getIndexFromHash(key);
if (matches(hashIdx, key))
return hashIdx;
int idx = hashIdx + 1;
while (idx < nodes.length) {
if (isEmpty(idx))
return null;
if (matches(hashIdx, key))
return idx;
else
idx++;
}
// Reached end
idx = 0;
while (idx < hashIdx) {
if (isEmpty(idx))
return null;
if (matches(hashIdx, key))
return idx;
else
idx++;
}
return null;
}
private boolean matches(int index, T1 key) {
if (isEmpty(index))
return false;
else
return getNode(index).key.equals(key);
}
@Override
public void put(T1 key, T2 value) throws Exception {
double alpha = getAlpha(size, nodes.length);
if (alpha >= ALPHA_LEVEL)
{
double newSize = ((double)nodes.length)/(ALPHA_LEVEL) * 2;
resize(nodes.length, (int) newSize);
}
Integer idx = IndexForPut(key);
if (idx == null)
throw new Exception("Table full");
else
put(idx, key, value);
}
private void resize(int oldSize, int newSize) throws Exception {
double alpha = getAlpha(oldSize, newSize);
if (alpha >= ALPHA_LEVEL)
throw new Exception("New size is not big enough. Alpha = " + alpha);
Object[] old = nodes;
nodes = new Object[newSize];
size = 0;
for (int i = 0; i < oldSize; i++)
{
if (!isEmpty(old[i]))
{
Node n = ((Node) old[i]);
put(n.key,n.value);
}
}
}
private double getAlpha(int oldSize, int newSize) {
double alpha = ((double)oldSize/(double)newSize);
return alpha;
}
private boolean isEmpty(Object node) {
return node == null || ((Node) node).key == null;
}
private boolean isEmpty(int idx) {
return nodes[idx] == null || getNode(idx).key == null;
}
private void put(int idx, T1 key, T2 value) {
if (nodes[idx] == null) {
Node n = new Node(key, value);
nodes[idx] = n;
} else {
Node n = getNode(idx);
n.key = key;
n.value = value;
}
size++;
}
private Node getNode(int idx) {
return (Node) nodes[idx];
}
@Override
public T2 get(T1 key) {
Integer idx = find(key);
if (idx == null)
return null;
else
return getNode(idx).value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment