/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.util; import java.util.AbstractSet; import java.util.BitSet; import java.util.Iterator; import java.util.NoSuchElementException; public abstract class IndexableObjectSet<E> extends AbstractSet<E> { private BitSet myBitSet; protected IndexableObjectSet(int size) { this(size, false); } protected IndexableObjectSet(int size, boolean full) { myBitSet = new BitSet(size); if (full) { myBitSet.set(0, size); } } protected abstract int getIndex(E e); protected abstract E getObject(int index); @Override public Iterator<E> iterator() { return new Iterator<E>() { private int myCurrent = 0; @Override public boolean hasNext() { return myBitSet.nextSetBit(myCurrent) != -1; } @Override public E next() { int nextSetBit = myBitSet.nextSetBit(myCurrent); if (nextSetBit == -1) throw new NoSuchElementException(); myCurrent = nextSetBit + 1; return getObject(nextSetBit); } @Override public void remove() { if (myCurrent == 0) throw new IllegalStateException(); myBitSet.set(myCurrent - 1, false); } }; } @Override public int size() { int result = 0; for (int i = 0; i < myBitSet.size(); i++) { if (myBitSet.get(i)) { result++; } } return result; } @Override public boolean isEmpty() { return myBitSet.isEmpty(); } @Override public boolean contains(Object o) { int index = getIndex((E) o); if (index == -1) return false; return myBitSet.get(index); } @Override public boolean add(E e) { int index = getIndex(e); if (index == -1) throw new IllegalArgumentException(); boolean was = myBitSet.get(index); myBitSet.set(index); return !was; } @Override public boolean remove(Object o) { int index = getIndex((E) o); if (index == -1) throw new IllegalArgumentException(); boolean contained = myBitSet.get(index); myBitSet.set(index, false); return contained; } public void add(int index) { myBitSet.set(index); } public void remove(int index) { myBitSet.set(index, false); } public void addAll(IndexableObjectSet<E> set) { myBitSet.or(set.myBitSet); } public void retainAll(IndexableObjectSet<E> set) { myBitSet.and(set.myBitSet); } public boolean contains(int varId) { return myBitSet.get(varId); } @Override public void clear() { myBitSet.clear(); } @Override public int hashCode() { return myBitSet.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof IndexableObjectSet) { IndexableObjectSet vs = (IndexableObjectSet) o; return vs.myBitSet.equals(myBitSet); } return super.equals(o); } }