/** * Decreasing the capacity of the table */ private void shrink() { int oldCapacity = data.length; if (oldCapacity == 1) return; E[] oldData = data; int[] oldMasks = masks; int newCapacity = oldCapacity >> 1; @SuppressWarnings("unchecked") E[] newData = (E[]) new Object[newCapacity]; int[] newMasks = new int[getMaskCapacity(logs, newCapacity)]; for (int i = 0; i < oldCapacity; i++) { E e = oldData[i]; if (e != null) addMask(logs, newData, newMasks, e, getFragment(logs, oldMasks, i)); } this.data = newData; this.masks = newMasks; }
private static <E> int removeMask(byte sl, E[] data, int[] masks, Object o, int mask) { int pos = LinearProbing.getPosition(data, o); if (data[pos] == null) return 0; // else int oldFragment = getFragment(sl, masks, pos); int newFragment = oldFragment & (~mask); if (newFragment == 0) remove(sl, data, masks, pos); else changeFragment(sl, masks, pos, oldFragment ^ newFragment); return oldFragment; }
@SuppressWarnings("unchecked") public ArraySlicedSet(int slices, int initialCapacity) { if (slices <= 0 || slices > MAX_SLICES) throw new IllegalArgumentException( "The nuber of slices should be between 1 and " + MAX_SLICES + ": " + slices); int capacity = LinearProbing.getInitialCapacity(initialCapacity); this.data = (E[]) new Object[capacity]; this.logs = (byte) upperLog(slices); this.masks = new int[getMaskCapacity(logs, capacity)]; this.sizes = new int[slices]; initSizes(); }
/** * Clears all slices of this {@link ArraySlicedSet}. After calling this * methods, all slices are empty. */ @SuppressWarnings("unchecked") public void clear() { int capacity = data.length >> 2; if (capacity == 0) capacity = 1; initSizes(); this.data = (E[]) new Object[capacity]; this.masks = new int[getMaskCapacity(logs, capacity)]; }
private static <E> void remove(byte sl, E[] data, int[] masks, int pos) { int oldFragment = getFragment(sl, masks, pos); for (;;) { int next = LinearProbing.getMovedPosition(data, pos); E moved = data[pos] = data[next]; int newFragment = getFragment(sl, masks, next); changeFragment(sl, masks, pos, oldFragment ^ newFragment); if (moved == null) return; // else pos = next; oldFragment = newFragment; } }
public boolean contains(int s, Object o) { if (o == null) throw new NullPointerException(); // to avoid problems in the middle of resizing, we copy data and masks // when they have the same size E[] d; int[] m; for (;;) { d = this.data; m = this.masks; if (m.length == getMaskCapacity(logs, d.length)) break; } int pos = LinearProbing.getPosition(d, o); if (d[pos] == null) return false; // else int mask = 1 << s; return ((getFragment(logs, m, pos) & mask) == mask); }
/** * Inserts a given element into the given slice * * @param s * the slice id * @param e * the elements to be inserted in to the given slice * @return {@code true} if the given element did not occur in the given * slice and thus was inserted. Otherwise {@code false} is returned * and nothing is modified. */ public boolean add(int s, E e) { if (e == null) throw new NullPointerException(); int mask = (1 << s); int oldMask = addMask(logs, data, masks, e, mask); int newMask = oldMask | mask; if (newMask == oldMask) return false; else if (oldMask == 0 && ++occupied == LinearProbing.getUpperSize(data.length)) enlarge(); sizes[s]++; return true; }
/** * Removes the given object from the given slice * * @param s * the slice id * @param o * the object that should be removed from the given slice * @return {@code true} if the given object is equal to some element of the * given slice; this element will be removed from the slice. If * there is no such an object, {@code false} is returned and nothing * is modified */ public boolean remove(int s, Object o) { if (o == null) throw new NullPointerException(); int mask = 1 << s; int oldMask = removeMask(logs, data, masks, o, mask); int newMask = oldMask & ~mask; if (newMask == oldMask) return false; // else if (newMask == 0 && --occupied == LinearProbing.getLowerSize(data.length)) shrink(); sizes[s]--; return true; }
/** * Removes all element of the given {@link Collection} from the given slice * * @param s * the slice id * @param c * the collection whose elements should be removed * @return {@code true} if at least one element is removed from the slice. * An element is removed if an equal element is present in the given * collection. If no elements are removed, {@code false} is returned * and nothing is modified. */ public boolean removeAll(int s, Collection<?> c) { boolean modified = false; for (Object o : c) { modified |= remove(s, o); } return modified; }
private static <E> int addMask(byte sl, E[] data, int[] masks, E e, int mask) { int pos = LinearProbing.getPosition(data, e); int oldMask = getFragment(sl, masks, pos); if (data[pos] == null) { data[pos] = e; changeFragment(sl, masks, pos, oldMask ^ mask); return 0; } // else int newMask = (oldMask | mask); if (newMask != oldMask) changeFragment(sl, masks, pos, oldMask ^ newMask); return oldMask; }
/** * Clears all slices of this {@link ArraySlicedSet}. After calling this * methods, all slices are empty. */ @SuppressWarnings("unchecked") public void clear() { int capacity = data.length >> 2; if (capacity == 0) capacity = 1; initSizes(); this.data = (E[]) new Object[capacity]; this.masks = new int[getMaskCapacity(logs, capacity)]; }
public boolean contains(int s, Object o) { if (o == null) throw new NullPointerException(); // to avoid problems in the middle of resizing, we copy data and masks // when they have the same size E[] d; int[] m; for (;;) { d = this.data; m = this.masks; if (m.length == getMaskCapacity(logs, d.length)) break; } int pos = LinearProbing.getPosition(d, o); if (d[pos] == null) return false; // else int mask = 1 << s; return ((getFragment(logs, m, pos) & mask) == mask); }
/** * Inserts a given element into the given slice * * @param s * the slice id * @param e * the elements to be inserted in to the given slice * @return {@code true} if the given element did not occur in the given * slice and thus was inserted. Otherwise {@code false} is returned * and nothing is modified. */ public boolean add(int s, E e) { if (e == null) throw new NullPointerException(); int mask = (1 << s); int oldMask = addMask(logs, data, masks, e, mask); int newMask = oldMask | mask; if (newMask == oldMask) return false; else if (oldMask == 0 && ++occupied == LinearProbing.getUpperSize(data.length)) enlarge(); sizes[s]++; return true; }
/** * Removes the given object from the given slice * * @param s * the slice id * @param o * the object that should be removed from the given slice * @return {@code true} if the given object is equal to some element of the * given slice; this element will be removed from the slice. If * there is no such an object, {@code false} is returned and nothing * is modified */ public boolean remove(int s, Object o) { if (o == null) throw new NullPointerException(); int mask = 1 << s; int oldMask = removeMask(logs, data, masks, o, mask); int newMask = oldMask & ~mask; if (newMask == oldMask) return false; // else if (newMask == 0 && --occupied == LinearProbing.getLowerSize(data.length)) shrink(); sizes[s]--; return true; }
/** * Removes all element of the given {@link Collection} from the given slice * * @param s * the slice id * @param c * the collection whose elements should be removed * @return {@code true} if at least one element is removed from the slice. * An element is removed if an equal element is present in the given * collection. If no elements are removed, {@code false} is returned * and nothing is modified. */ public boolean removeAll(int s, Collection<?> c) { boolean modified = false; for (Object o : c) { modified |= remove(s, o); } return modified; }
/** * Decreasing the capacity of the table */ private void shrink() { int oldCapacity = data.length; if (oldCapacity == 1) return; E[] oldData = data; int[] oldMasks = masks; int newCapacity = oldCapacity >> 1; @SuppressWarnings("unchecked") E[] newData = (E[]) new Object[newCapacity]; int[] newMasks = new int[getMaskCapacity(logs, newCapacity)]; for (int i = 0; i < oldCapacity; i++) { E e = oldData[i]; if (e != null) addMask(logs, newData, newMasks, e, getFragment(logs, oldMasks, i)); } this.data = newData; this.masks = newMasks; }
@SuppressWarnings("unchecked") public ArraySlicedSet(int slices, int initialCapacity) { if (slices <= 0 || slices > MAX_SLICES) throw new IllegalArgumentException( "The nuber of slices should be between 1 and " + MAX_SLICES + ": " + slices); int capacity = LinearProbing.getInitialCapacity(initialCapacity); this.data = (E[]) new Object[capacity]; this.logs = (byte) upperLog(slices); this.masks = new int[getMaskCapacity(logs, capacity)]; this.sizes = new int[slices]; initSizes(); }
private static <E> int removeMask(byte sl, E[] data, int[] masks, Object o, int mask) { int pos = LinearProbing.getPosition(data, o); if (data[pos] == null) return 0; // else int oldFragment = getFragment(sl, masks, pos); int newFragment = oldFragment & (~mask); if (newFragment == 0) remove(sl, data, masks, pos); else changeFragment(sl, masks, pos, oldFragment ^ newFragment); return oldFragment; }
private static <E> void remove(byte sl, E[] data, int[] masks, int pos) { int oldFragment = getFragment(sl, masks, pos); for (;;) { int next = LinearProbing.getMovedPosition(data, pos); E moved = data[pos] = data[next]; int newFragment = getFragment(sl, masks, next); changeFragment(sl, masks, pos, oldFragment ^ newFragment); if (moved == null) return; // else pos = next; oldFragment = newFragment; } }
/** * Clears all slices of this {@link ArraySlicedSet}. After calling this * methods, all slices are empty. */ @SuppressWarnings("unchecked") public void clear() { int capacity = data.length >> 2; if (capacity == 0) capacity = 1; initSizes(); this.data = (E[]) new Object[capacity]; this.masks = new int[getMaskCapacity(logs, capacity)]; }