package hashtables.sequential; import java.util.Collection; import java.util.Random; import contention.abstractions.CompositionalIntSet; /** * Sequential hash table implementation of integer set * @author Vincent Gramoli * */ public class SequentialHashIntSet implements CompositionalIntSet { private Node[] table; int tableSize; /** The thread-private PRNG */ final private static ThreadLocal<Random> s_random = new ThreadLocal<Random>() { @Override protected synchronized Random initialValue() { return new Random(); } }; public SequentialHashIntSet(int size) { tableSize = size; table = new Node[tableSize]; } public SequentialHashIntSet() { this(contention.benchmark.Parameters.size); } @Override public void fill(final int range, final long size) { while (this.size() < size) { this.addInt(s_random.get().nextInt(range)); } } private int hash(int value) { return value % tableSize; } public boolean addInt(int value) { int h = hash(value); Node node = table[h]; if (node == null) { table[h] = new Node(value); return true; } if (node.getValue() == value) { return false; } Node next = node.getNext(); while (next != null) { node = next; next = node.getNext(); if (node.getValue() == value) { return false; } } node.setNext(new Node(value)); return true; } public boolean removeInt(int value) { int h = hash(value); Node node = table[h]; if (node == null) { return false; } Node next = node.getNext(); if (node.getValue() == value) { table[h] = next; node.setNext(next); return true; } while (next != null) { if (next.getValue() == value) { node.setNext(next.getNext()); return true; } node = next; next = node.getNext(); } return false; } public boolean containsInt(int value) { int h = hash(value); Node node = table[h]; if (node == null) { return false; } while (node != null) { if (node.getValue() == value) { return true; } node = node.getNext(); } return false; } @Override public boolean addAll(Collection<Integer> c) { boolean result = true; for (Integer x : c) result &= this.addInt(x); return result; } @Override public boolean removeAll(Collection<Integer> c) { boolean result = true; for (Integer x : c) result &= this.removeInt(x); return result; } public int size() { int s = 0; for (int i = 0; i < tableSize; i++) { Node node = table[i]; while (node != null) { s++; node = node.getNext(); } } return s; } public class Node { final private int m_value; private Node m_next; public Node(int value, Node next) { m_value = value; m_next = next; } public Node(int value) { this(value, null); } public int getValue() { return m_value; } public void setNext(Node next) { m_next = next; } public Node getNext() { return m_next; } } /** * This is called after the JVM warmup phase * to make sure the data structure is well initalized. * No need to do anything for this. */ public void clear() { tableSize = contention.benchmark.Parameters.size; table = new Node[tableSize]; } @Override public Object getInt(int value) { int h = hash(value); Node node = table[h]; if (node == null) { return false; } while (node != null) { if (node.getValue() == value) { return true; } node = node.getNext(); } return false; } @Override public Object putIfAbsent(int x, int y) { if (!containsInt(x)) addInt(y); return null; } }