diff --git a/src/main/java/io/usethesource/vallang/impl/util/collections/ShareableValuesHashSet.java b/src/main/java/io/usethesource/vallang/impl/util/collections/ShareableValuesHashSet.java deleted file mode 100644 index faa749837..000000000 --- a/src/main/java/io/usethesource/vallang/impl/util/collections/ShareableValuesHashSet.java +++ /dev/null @@ -1,397 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 Centrum Wiskunde en Informatica (CWI) -* All rights reserved. This program and the accompanying materials -* are made available under the terms of the Eclipse Public License v1.0 -* which accompanies this distribution, and is available at -* http://www.eclipse.org/legal/epl-v10.html -* -* Contributors: -* Arnold Lankamp - interfaces and implementation -* Jurgen Vinju - CF annotation, maintenance and removal of unused methods -*******************************************************************************/ -package io.usethesource.vallang.impl.util.collections; - -import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.checkerframework.checker.initialization.qual.UnknownInitialization; -import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import io.usethesource.vallang.IValue; -import io.usethesource.vallang.impl.persistent.ValueFactory; - -/** - * A specialized version of the ShareableSet, specifically meant for storing values. - * - * @author Arnold Lankamp - */ -public final class ShareableValuesHashSet implements Iterable{ - private final static int INITIAL_LOG_SIZE = 4; - - private int modSize; - private int hashMask; - - private @Nullable Entry[] data; - - private int threshold; - - private int load; - - private int currentHashCode; - - @SuppressWarnings("unchecked") - public ShareableValuesHashSet(){ - super(); - - modSize = INITIAL_LOG_SIZE; - int tableSize = 1 << modSize; - hashMask = tableSize - 1; - data = (Entry[]) new Entry[tableSize]; - - threshold = tableSize; - - load = 0; - - currentHashCode = 0; - } - - public ShareableValuesHashSet(ShareableValuesHashSet shareableValuesHashSet){ - super(); - - modSize = shareableValuesHashSet.modSize; - int tableSize = 1 << modSize; - hashMask = tableSize - 1; - data = shareableValuesHashSet.data.clone(); - - threshold = tableSize; - - load = shareableValuesHashSet.load; - - currentHashCode = shareableValuesHashSet.currentHashCode; - } - - @SuppressWarnings("unchecked") - public void clear(){ - modSize = INITIAL_LOG_SIZE; - int tableSize = 1 << modSize; - hashMask = tableSize - 1; - data = (Entry[]) new Entry[tableSize]; - - threshold = tableSize; - - load = 0; - - currentHashCode = 0; - } - - @SuppressWarnings("unchecked") - private void rehash(){ - modSize++; - int tableSize = 1 << modSize; - hashMask = tableSize - 1; - Entry[] newData = (Entry[]) new Entry[tableSize]; - - threshold = tableSize; - - @Nullable Entry[] oldData = data; - for (int i = oldData.length - 1; i >= 0; i--) { - Entry entry = oldData[i]; - - if (entry != null) { - // Determine the last unchanged entry chain. - Entry lastUnchangedEntryChain = entry; - int newLastUnchangedEntryChainIndex = entry.hash & hashMask; - - Entry e = entry.next; - while (e != null) { - int newIndex = e.hash & hashMask; - if (newIndex != newLastUnchangedEntryChainIndex) { - lastUnchangedEntryChain = e; - newLastUnchangedEntryChainIndex = newIndex; - } - - e = e.next; - } - - newData[newLastUnchangedEntryChainIndex] = lastUnchangedEntryChain; - - // Reconstruct the other entries (if necessary). - while (entry != lastUnchangedEntryChain && entry != null) { - int hash = entry.hash; - int position = hash & hashMask; - newData[position] = new Entry<>(hash, entry.value, newData[position]); - - entry = entry.next; - } - } - } - - data = newData; - } - - private void ensureCapacity(){ - if(load > threshold){ - rehash(); - } - } - - public boolean add(IValue value){ - ensureCapacity(); - - int hash = value.hashCode(); - int position = hash & hashMask; - - Entry currentStartEntry = data[position]; - // Check if the value is already in here. - if(currentStartEntry != null){ - Entry entry = currentStartEntry; - do{ - if(hash == entry.hash && entry.value.equals(value)){ - return false; // Return false if it's already present. - } - - entry = entry.next; - }while(entry != null); - } - - data[position] = new Entry<>(hash, value, currentStartEntry); // Insert the new entry. - - load++; - - currentHashCode ^= hash; // Update the current hashcode of this map. - - return true; - } - - public boolean contains(Object object){ - IValue value = (IValue) object; - - int hash = value.hashCode(); - int position = hash & hashMask; - - Entry entry = data[position]; - while(entry != null){ - if(hash == entry.hash && value.equals(entry.value)) return true; - - entry = entry.next; - } - - return false; - } - - public boolean remove(Object object){ - IValue value = (IValue) object; - - int hash = value.hashCode(); - int position = hash & hashMask; - - Entry currentStartEntry = data[position]; - - if (currentStartEntry != null) { - Entry entry = currentStartEntry; - do { - if (hash == entry.hash && entry.value.equals(value)) { - Entry e = data[position]; - - data[position] = entry.next; - // Reconstruct the other entries (if necessary). - while (e != entry && e != null) { - data[position] = new Entry<>(e.hash, e.value, data[position]); - - e = e.next; - } - - load--; - - currentHashCode ^= hash; // Update the current hashcode of this set. - - return true; - } - - entry = entry.next; - } while(entry != null); - } - - return false; - } - - public int size(){ - return load; - } - - public boolean isEmpty(){ - return (load == 0); - } - - public Iterator iterator(){ - return new SetIterator(data); - } - - public boolean addAll(Collection collection){ - boolean changed = false; - - Iterator collectionIterator = collection.iterator(); - while(collectionIterator.hasNext()){ - changed |= add(collectionIterator.next()); - } - - return changed; - } - - @Override - public String toString(){ - StringBuilder buffer = new StringBuilder(); - - buffer.append('{'); - for(int i = 0; i < data.length; i++){ - buffer.append('['); - Entry e = data[i]; - if(e != null){ - buffer.append(e); - - e = e.next; - - while(e != null){ - buffer.append(','); - buffer.append(e); - - e = e.next; - } - } - buffer.append(']'); - } - buffer.append('}'); - - return buffer.toString(); - } - - public int hashCode(){ - return currentHashCode; - } - - private boolean containsTruelyEqual(IValue value){ - int hash = value.hashCode(); - int position = hash & hashMask; - - Entry entry = data[position]; - while(entry != null){ - if(hash == entry.hash && value.equals(entry.value)) return true; - - entry = entry.next; - } - - return false; - } - - public boolean equals(@Nullable Object o){ - if(o == null) { - return false; - } - - if(o.getClass() == getClass()){ - ShareableValuesHashSet other = (ShareableValuesHashSet) o; - - if(other.currentHashCode != currentHashCode) return false; - if(other.size() != size()) return false; - - if(isEmpty()) return true; // No need to check if the sets are empty. - - Iterator otherIterator = other.iterator(); - while(otherIterator.hasNext()){ - if(!containsTruelyEqual(otherIterator.next())) return false; - } - return true; - } - - return false; - } - - private static class Entry{ - public final int hash; - public final V value; - - public final @Nullable Entry next; - - public Entry(int hash, V value, @Nullable Entry next){ - super(); - - this.hash = hash; - this.value = value; - - this.next = next; - } - - public String toString(){ - StringBuilder buffer = new StringBuilder(); - - buffer.append('<'); - buffer.append(value); - buffer.append('>'); - - return buffer.toString(); - } - } - - private static class SetIterator implements Iterator{ - private final @Nullable Entry[] data; - - private @Nullable Entry current; - private int index; - - public SetIterator(@Nullable Entry[] entries) { - super(); - - data = entries; - - index = data.length - 1; - current = new Entry<>(0, ValueFactory.getInstance().bool(true) /* dummy */, data[index]); - locateNext(data); - } - - private void locateNext(@UnknownInitialization SetIterator this, @Nullable Entry[] data) { - Entry next = current != null ? current.next : null; - - if (next != null) { - this.current = next; - return; - } - - for (int i = this.index - 1; i >= 0 ; i--) { - @Nullable Entry entry = data[i]; - if (entry != null) { - this.current = entry; - this.index = i; - return; - } - } - - this.current = null; - this.index = 0; - } - - @EnsuresNonNullIf(expression="this.current", result=true) - @Override - public boolean hasNext(@UnknownInitialization SetIterator this) { - return (current != null); - } - - @Override - public IValue next(){ - if (!hasNext()) { - throw new NoSuchElementException("There are no more elements in this iteration"); - } - - @NonNull IValue value = current.value; - locateNext(data); - - return value; - } - - @Override - public void remove() { - throw new UnsupportedOperationException("This iterator doesn't support removal."); - } - } -}