com.ibm.wala.util.intset.MutableSharedBitVectorIntSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.ibm.wala.util Show documentation
Show all versions of com.ibm.wala.util Show documentation
T. J. Watson Libraries for Analysis
The newest version!
/*
* Copyright (c) 2002 - 2006 IBM Corporation.
* 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:
* IBM Corporation - initial API and implementation
*/
package com.ibm.wala.util.intset;
import com.ibm.wala.util.collections.CompoundIntIterator;
import com.ibm.wala.util.collections.EmptyIntIterator;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.UnimplementedError;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
/**
* The shared bit vector implementation described by [Heintze 1999] TODO: much optimization
* possible.
*/
public class MutableSharedBitVectorIntSet implements MutableIntSet {
private static final long serialVersionUID = -6630888692508092370L;
private static final boolean DEBUG = false;
private static final boolean PARANOID = false;
private static final int OVERFLOW = 20;
private @Nullable MutableSparseIntSet privatePart;
private @Nullable BitVectorIntSet sharedPart;
/** */
public MutableSharedBitVectorIntSet() {}
/**
* @throws IllegalArgumentException if set is null
*/
public MutableSharedBitVectorIntSet(MutableSharedBitVectorIntSet set) {
if (set == null) {
throw new IllegalArgumentException("set is null");
}
if (set.privatePart != null) {
this.privatePart = MutableSparseIntSet.make(set.privatePart);
}
this.sharedPart = set.sharedPart;
}
/**
* @throws IllegalArgumentException if s is null
*/
public MutableSharedBitVectorIntSet(SparseIntSet s) {
if (s == null) {
throw new IllegalArgumentException("s is null");
}
if (s.isEmpty()) {
return;
}
this.privatePart = MutableSparseIntSet.make(s);
checkOverflow();
if (PARANOID) {
checkIntegrity();
}
}
/**
* @throws IllegalArgumentException if s is null
*/
public MutableSharedBitVectorIntSet(BitVectorIntSet s) {
if (s == null) {
throw new IllegalArgumentException("s is null");
}
copyValue(s);
if (PARANOID) {
checkIntegrity();
}
}
private void copyValue(BitVectorIntSet s) {
if (s.isEmpty()) {
sharedPart = null;
privatePart = null;
} else if (s.size() < OVERFLOW) {
sharedPart = null;
privatePart = MutableSparseIntSet.make(s);
} else {
sharedPart = BitVectorRepository.findOrCreateSharedSubset(s);
if (sharedPart.size() == s.size()) {
privatePart = null;
} else {
BitVectorIntSet temp = new BitVectorIntSet(s);
temp.removeAll(sharedPart);
if (!temp.isEmpty()) {
privatePart = MutableSparseIntSet.make(temp);
} else {
privatePart = null;
}
}
}
if (PARANOID) {
checkIntegrity();
}
}
/** */
private void checkIntegrity() {
assert privatePart == null || !privatePart.isEmpty();
//noinspection AssertWithSideEffects
assert sharedPart == null || !sharedPart.isEmpty();
if (privatePart != null && sharedPart != null) {
assert privatePart.intersection(sharedPart).isEmpty();
}
}
/** */
private void checkOverflow() {
if (PARANOID) {
checkIntegrity();
}
if (privatePart != null && privatePart.size() > OVERFLOW) {
BitVectorIntSet temp;
if (sharedPart == null) {
temp = new BitVectorIntSet(privatePart);
} else {
temp = new BitVectorIntSet(sharedPart);
// when we call findOrCreateSharedSubset, we will ask size() on temp.
// so use addAll instead of addAllOblivious: which incrementally
// updates the population count.
temp.addAll(privatePart);
}
sharedPart = BitVectorRepository.findOrCreateSharedSubset(temp);
temp.removeAll(sharedPart);
if (!temp.isEmpty()) privatePart = MutableSparseIntSet.make(temp);
else privatePart = null;
}
if (PARANOID) {
checkIntegrity();
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#contains(int)
*/
@Override
public boolean contains(int i) {
if (privatePart != null && privatePart.contains(i)) {
return true;
}
if (sharedPart != null && sharedPart.contains(i)) {
return true;
}
return false;
}
/**
* @see com.ibm.wala.util.intset.IntSet#intersection(com.ibm.wala.util.intset.IntSet)
*/
@Override
public IntSet intersection(IntSet that) {
if (that == null) {
throw new IllegalArgumentException("null that");
}
if (that instanceof MutableSharedBitVectorIntSet) {
return intersection((MutableSharedBitVectorIntSet) that);
} else if (that instanceof BitVectorIntSet) {
MutableSharedBitVectorIntSet m = new MutableSharedBitVectorIntSet((BitVectorIntSet) that);
return intersection(m);
} else if (that instanceof SparseIntSet) {
BitVectorIntSet bv = new BitVectorIntSet(that);
return intersection(bv);
} else {
// really slow. optimize as needed.
BitVectorIntSet result = new BitVectorIntSet();
for (IntIterator it = intIterator(); it.hasNext(); ) {
int x = it.next();
if (that.contains(x)) {
result.add(x);
}
}
return result;
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#union(com.ibm.wala.util.intset.IntSet)
*/
@Override
public IntSet union(IntSet that) {
MutableSharedBitVectorIntSet temp = new MutableSharedBitVectorIntSet();
temp.addAll(this);
temp.addAll(that);
return temp;
}
/**
* @see com.ibm.wala.util.intset.IntSet#intersection(com.ibm.wala.util.intset.IntSet)
*/
public IntSet intersection(MutableSharedBitVectorIntSet that) {
MutableSparseIntSet t = makeSparseCopy();
t.intersectWith(that);
MutableSharedBitVectorIntSet result = new MutableSharedBitVectorIntSet(t);
if (PARANOID) {
checkIntegrity();
}
return result;
}
/**
* @see com.ibm.wala.util.intset.IntSet#isEmpty()
*/
@Override
public boolean isEmpty() {
return privatePart == null && sharedPart == null;
}
/**
* @see com.ibm.wala.util.intset.IntSet#size()
*/
@Override
public int size() {
int result = 0;
result += (privatePart == null) ? 0 : privatePart.size();
result += (sharedPart == null) ? 0 : sharedPart.size();
return result;
}
/**
* @see IntSet#intIterator()
*/
@Override
public IntIterator intIterator() {
if (privatePart == null) {
return (sharedPart == null) ? EmptyIntIterator.instance() : sharedPart.intIterator();
} else {
return (sharedPart == null)
? privatePart.intIterator()
: new CompoundIntIterator(privatePart.intIterator(), sharedPart.intIterator());
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#foreach(com.ibm.wala.util.intset.IntSetAction)
*/
@Override
public void foreach(IntSetAction action) {
if (privatePart != null) {
privatePart.foreach(action);
}
if (sharedPart != null) {
sharedPart.foreach(action);
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#foreachExcluding(com.ibm.wala.util.intset.IntSet,
* com.ibm.wala.util.intset.IntSetAction)
*/
@Override
public void foreachExcluding(IntSet X, IntSetAction action) {
if (X instanceof MutableSharedBitVectorIntSet) {
foreachExcludingInternal((MutableSharedBitVectorIntSet) X, action);
} else {
foreachExcludingGeneral(X, action);
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#foreachExcluding(com.ibm.wala.util.intset.IntSet,
* com.ibm.wala.util.intset.IntSetAction)
*/
private void foreachExcludingInternal(MutableSharedBitVectorIntSet X, IntSetAction action) {
if (sameSharedPart(this, X)) {
if (privatePart != null) {
if (X.privatePart != null) {
privatePart.foreachExcluding(X.privatePart, action);
} else {
privatePart.foreach(action);
}
}
} else {
if (privatePart != null) {
privatePart.foreachExcluding(X, action);
}
if (sharedPart != null) {
sharedPart.foreachExcluding(X.makeDenseCopy(), action);
}
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#foreachExcluding(com.ibm.wala.util.intset.IntSet,
* com.ibm.wala.util.intset.IntSetAction)
*/
private void foreachExcludingGeneral(IntSet X, IntSetAction action) {
if (privatePart != null) {
privatePart.foreachExcluding(X, action);
}
if (sharedPart != null) {
sharedPart.foreachExcluding(X, action);
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#max()
*/
@Override
public int max() {
int result = -1;
if (privatePart != null && !privatePart.isEmpty()) {
result = Math.max(result, privatePart.max());
}
if (sharedPart != null) {
result = Math.max(result, sharedPart.max());
}
return result;
}
/**
* @see com.ibm.wala.util.intset.IntSet#sameValue(com.ibm.wala.util.intset.IntSet)
*/
@Override
public boolean sameValue(IntSet that) throws IllegalArgumentException, UnimplementedError {
if (that == null) {
throw new IllegalArgumentException("that == null");
}
if (that instanceof MutableSharedBitVectorIntSet) {
return sameValue((MutableSharedBitVectorIntSet) that);
} else if (that instanceof SparseIntSet) {
return sameValue((SparseIntSet) that);
} else if (that instanceof BimodalMutableIntSet) {
return that.sameValue(makeSparseCopy());
} else if (that instanceof BitVectorIntSet) {
return sameValue((BitVectorIntSet) that);
} else if (that instanceof SemiSparseMutableIntSet) {
return that.sameValue(this);
} else {
Assertions.UNREACHABLE("unexpected class " + that.getClass());
return false;
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#sameValue(com.ibm.wala.util.intset.IntSet)
*/
private boolean sameValue(SparseIntSet that) {
if (size() != that.size()) {
return false;
}
if (sharedPart == null) {
if (privatePart == null)
/* both parts empty, and that has same (i.e. 0) size */
return true;
else return privatePart.sameValue(that);
} else {
/* sharedPart != null */
return makeSparseCopy().sameValue(that);
}
}
private boolean sameValue(BitVectorIntSet that) {
if (size() != that.size()) {
return false;
}
if (sharedPart == null) {
if (privatePart == null)
/* both parts empty, and that has same (i.e. 0) size */
return true;
else
// shared part is null and size is same, so number of bits is low
return that.makeSparseCopy().sameValue(privatePart);
} else {
if (privatePart == null) return sharedPart.sameValue(that);
else
/* sharedPart != null */
return makeDenseCopy().sameValue(that);
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#sameValue(com.ibm.wala.util.intset.IntSet)
*/
private boolean sameValue(MutableSharedBitVectorIntSet that) {
if (size() != that.size()) {
return false;
}
if (sharedPart == null) {
if (privatePart == null) {
/* we must have size() == that.size() == 0 */
return true;
} else {
/* sharedPart == null, privatePart != null */
if (that.sharedPart == null) {
if (that.privatePart == null) {
return privatePart.isEmpty();
} else {
return privatePart.sameValue(that.privatePart);
}
} else {
/* sharedPart = null, privatePart != null, that.sharedPart != null */
if (that.privatePart == null) {
return privatePart.sameValue(that.sharedPart);
} else {
BitVectorIntSet temp = new BitVectorIntSet(that.sharedPart);
temp.addAllOblivious(that.privatePart);
return privatePart.sameValue(temp);
}
}
}
} else {
/* sharedPart != null */
if (privatePart == null) {
if (that.privatePart == null) {
return sharedPart.sameValue(that.sharedPart);
} else {
/* privatePart == null, sharedPart != null, that.privatePart != null */
if (that.sharedPart == null) {
return sharedPart.sameValue(that.privatePart);
} else {
MutableSparseIntSet t = that.makeSparseCopy();
return sharedPart.sameValue(t);
}
}
} else {
/* sharedPart != null , privatePart != null */
if (that.sharedPart == null) {
Assertions.UNREACHABLE();
return false;
} else {
/* that.sharedPart != null */
if (that.privatePart == null) {
SparseIntSet s = makeSparseCopy();
return s.sameValue(that.sharedPart);
} else {
/* that.sharedPart != null, that.privatePart != null */
/* assume reference equality for canonical shared part */
if (sharedPart == that.sharedPart) {
return privatePart.sameValue(that.privatePart);
} else {
SparseIntSet s1 = makeSparseCopy();
SparseIntSet s2 = that.makeSparseCopy();
return s1.sameValue(s2);
}
}
}
}
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#isSubset(com.ibm.wala.util.intset.IntSet)
*/
@Override
public boolean isSubset(IntSet that) {
if (that == null) {
throw new IllegalArgumentException("null that");
}
if (that instanceof MutableSharedBitVectorIntSet) {
return isSubset((MutableSharedBitVectorIntSet) that);
} else {
// really slow. optimize as needed.
for (IntIterator it = intIterator(); it.hasNext(); ) {
if (!that.contains(it.next())) {
return false;
}
}
return true;
}
}
/**
* @see com.ibm.wala.util.intset.IntSet#sameValue(com.ibm.wala.util.intset.IntSet)
*/
private boolean isSubset(MutableSharedBitVectorIntSet that) {
if (size() > that.size()) {
return false;
}
if (sharedPart == null) {
if (privatePart == null) {
return true;
} else {
if (that.sharedPart == null) {
return privatePart.isSubset(that.privatePart);
} else {
/* sharedPart == null, that.sharedPart != null */
if (that.privatePart == null) {
return privatePart.isSubset(that.sharedPart);
} else {
SparseIntSet s1 = that.makeSparseCopy();
return privatePart.isSubset(s1);
}
}
}
} else {
/* sharedPart != null */
if (privatePart == null) {
/* sharedPart != null, privatePart == null */
if (that.privatePart == null) {
if (that.sharedPart == null) {
return false;
} else {
return sharedPart.isSubset(that.sharedPart);
}
} else {
if (that.sharedPart == null) {
return sharedPart.isSubset(that.privatePart);
} else {
SparseIntSet s1 = that.makeSparseCopy();
return sharedPart.isSubset(s1);
}
}
} else {
/* sharedPart != null, privatePart != null */
if (that.privatePart == null) {
return privatePart.isSubset(that.sharedPart) && sharedPart.isSubset(that.sharedPart);
} else {
/* sharedPart != null, privatePart!= null, that.privatePart != null */
if (that.sharedPart == null) {
return privatePart.isSubset(that.privatePart) && sharedPart.isSubset(that.privatePart);
} else {
/*
* sharedPart != null, privatePart!= null, that.privatePart != null, that.sharedPart != null
*/
if (sharedPart.isSubset(that.sharedPart)) {
if (privatePart.isSubset(that.privatePart)) {
return true;
} else {
SparseIntSet s1 = that.makeSparseCopy();
return privatePart.isSubset(s1);
}
} else {
/* !sharedPart.isSubset(that.sharedPart) */
BitVectorIntSet temp = new BitVectorIntSet(sharedPart);
temp.removeAll(that.sharedPart);
if (temp.isSubset(that.privatePart)) {
/* sharedPart.isSubset(that) */
if (privatePart.isSubset(that.privatePart)) {
return true;
} else {
MutableSparseIntSet t = MutableSparseIntSet.make(privatePart);
t.removeAll(that.privatePart);
if (t.isSubset(that.sharedPart)) {
return true;
} else {
return false;
}
}
} else {
/*
* !((sharedPart-that.sharedPart).isSubset(that.privatePart)) i.e some bit in my shared part is in neither that's
* sharedPart nor that's privatePart, hence I am not a subset of that
*/
return false;
}
}
}
}
}
}
}
@Override
public void copySet(IntSet set) {
if (set instanceof MutableSharedBitVectorIntSet) {
MutableSharedBitVectorIntSet other = (MutableSharedBitVectorIntSet) set;
if (other.privatePart != null) {
this.privatePart = MutableSparseIntSet.make(other.privatePart);
} else {
this.privatePart = null;
}
this.sharedPart = other.sharedPart;
} else {
// really slow. optimize as needed.
clear();
addAll(set);
}
if (PARANOID) {
checkIntegrity();
}
}
@Override
public boolean addAll(IntSet set) throws IllegalArgumentException {
if (set == null) {
throw new IllegalArgumentException("set == null");
}
if (set instanceof MutableSharedBitVectorIntSet) {
boolean result = addAll((MutableSharedBitVectorIntSet) set);
if (PARANOID) {
checkIntegrity();
}
return result;
} else if (set instanceof SparseIntSet) {
boolean result = addAllInternal((SparseIntSet) set);
if (PARANOID) {
checkIntegrity();
}
return result;
} else if (set instanceof BitVectorIntSet) {
boolean result = addAllInternal((BitVectorIntSet) set);
if (PARANOID) {
checkIntegrity();
}
return result;
} else if (set instanceof DebuggingMutableIntSet) {
SparseIntSet temp = new SparseIntSet(set);
boolean result = addAllInternal(temp);
if (PARANOID) {
checkIntegrity();
}
return result;
} else {
// really slow. optimize as needed.
boolean result = false;
for (IntIterator it = set.intIterator(); it.hasNext(); ) {
int x = it.next();
if (!contains(x)) {
result = true;
add(x);
}
}
return result;
}
}
private boolean addAllInternal(BitVectorIntSet set) {
// should have hijacked this case before getting here!
assert sharedPart != set;
if (privatePart == null) {
if (sharedPart == null) {
copyValue(set);
return !set.isEmpty();
}
}
BitVectorIntSet temp = makeDenseCopy();
boolean result = temp.addAll(set);
copyValue(temp);
return result;
}
@NullUnmarked
private boolean addAllInternal(@Nullable SparseIntSet set) {
if (privatePart == null) {
if (sharedPart == null) {
if (!set.isEmpty()) {
privatePart = MutableSparseIntSet.make(set);
sharedPart = null;
checkOverflow();
return true;
} else {
return false;
}
} else {
privatePart = MutableSparseIntSet.make(set);
privatePart.removeAll(sharedPart);
if (privatePart.isEmpty()) {
privatePart = null;
return false;
} else {
checkOverflow();
return true;
}
}
} else {
/* privatePart != null */
if (sharedPart == null) {
boolean result = privatePart.addAll(set);
checkOverflow();
return result;
} else {
int oldSize = privatePart.size();
privatePart.addAll(set);
privatePart.removeAll(sharedPart);
boolean result = privatePart.size() > oldSize;
checkOverflow();
return result;
}
}
}
private boolean addAll(MutableSharedBitVectorIntSet set) {
if (set.isEmpty()) {
return false;
}
if (isEmpty()) {
if (set.privatePart != null) {
privatePart = MutableSparseIntSet.make(set.privatePart);
}
sharedPart = set.sharedPart;
return true;
}
if (set.sharedPart == null) {
return addAllInternal(set.privatePart);
} else {
// set.sharedPart != null
if (sameSharedPart(this, set)) {
if (set.privatePart == null) {
return false;
} else {
return addAllInternal(set.privatePart);
}
} else {
// !sameSharedPart
if (set.privatePart == null) {
if (sharedPart == null || sharedPart.isSubset(set.sharedPart)) {
// a heuristic that should be profitable if this condition usually
// holds.
int oldSize = size();
if (privatePart != null) {
privatePart.removeAll(set.sharedPart);
privatePart = privatePart.isEmpty() ? null : privatePart;
}
sharedPart = set.sharedPart;
return size() > oldSize;
} else {
BitVectorIntSet temp = makeDenseCopy();
boolean b = temp.addAll(set.sharedPart);
if (b) {
// a heuristic: many times these are the same value,
// so avoid looking up the shared subset in the bv repository
if (temp.sameValue(set.sharedPart)) {
this.privatePart = null;
this.sharedPart = set.sharedPart;
} else {
copyValue(temp);
}
}
return b;
}
} else {
// set.privatePart != null;
BitVectorIntSet temp = makeDenseCopy();
BitVectorIntSet other = set.makeDenseCopy();
boolean b = temp.addAll(other);
if (b) {
// a heuristic: many times these are the same value,
// so avoid looking up the shared subset in the bv repository
if (temp.sameValue(other)) {
this.privatePart = MutableSparseIntSet.make(set.privatePart);
this.sharedPart = set.sharedPart;
} else {
// System.err.println("COPY " + this + " " + set);
copyValue(temp);
}
}
return b;
}
}
}
}
@Override
public boolean add(int i) {
if (privatePart == null) {
if (sharedPart == null) {
privatePart = MutableSparseIntSet.makeEmpty();
privatePart.add(i);
return true;
} else {
if (sharedPart.contains(i)) {
return false;
} else {
privatePart = MutableSparseIntSet.makeEmpty();
privatePart.add(i);
return true;
}
}
} else {
if (sharedPart == null) {
boolean result = privatePart.add(i);
checkOverflow();
return result;
} else {
if (sharedPart.contains(i)) {
return false;
} else {
boolean result = privatePart.add(i);
checkOverflow();
return result;
}
}
}
}
@Override
public boolean remove(int i) {
if (privatePart != null) {
if (privatePart.contains(i)) {
privatePart.remove(i);
if (privatePart.isEmpty()) {
privatePart = null;
}
return true;
}
}
if (sharedPart != null) {
if (sharedPart.contains(i)) {
privatePart = makeSparseCopy();
privatePart.remove(i);
if (privatePart.isEmpty()) {
privatePart = null;
}
sharedPart = null;
checkOverflow();
return true;
}
}
return false;
}
@Override
public void intersectWith(IntSet set) {
if (set instanceof MutableSharedBitVectorIntSet) {
intersectWithInternal((MutableSharedBitVectorIntSet) set);
} else if (set instanceof BitVectorIntSet) {
intersectWithInternal(new MutableSharedBitVectorIntSet((BitVectorIntSet) set));
} else {
// this is really slow. optimize as needed.
for (IntIterator it = intIterator(); it.hasNext(); ) {
int x = it.next();
if (!set.contains(x)) {
remove(x);
}
}
}
if (DEBUG) {
if (privatePart != null && sharedPart != null)
assert privatePart.intersection(sharedPart).isEmpty();
}
}
private void intersectWithInternal(MutableSharedBitVectorIntSet set) {
if (sharedPart != null) {
if (sameSharedPart(this, set)) {
// no need to intersect shared part
if (privatePart != null) {
if (set.privatePart == null) {
privatePart = null;
} else {
privatePart.intersectWith(set.privatePart);
if (privatePart.isEmpty()) {
privatePart = null;
}
}
}
} else {
// not the same shared part
if (set.sharedPart == null) {
if (set.privatePart == null) {
privatePart = null;
sharedPart = null;
} else {
MutableSparseIntSet temp = MutableSparseIntSet.make(set.privatePart);
temp.intersectWith(this);
sharedPart = null;
if (temp.isEmpty()) {
privatePart = null;
} else {
privatePart = temp;
checkOverflow();
}
}
} else {
// set.sharedPart != null
BitVectorIntSet b = makeDenseCopy();
b.intersectWith(set.makeDenseCopy());
copyValue(b);
}
}
} else {
if (privatePart != null) {
privatePart.intersectWith(set);
if (privatePart.isEmpty()) {
privatePart = null;
}
}
}
if (PARANOID) {
checkIntegrity();
}
}
public static boolean sameSharedPart(
MutableSharedBitVectorIntSet a, MutableSharedBitVectorIntSet b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
if (a == null) {
throw new IllegalArgumentException("a is null");
}
return a.sharedPart == b.sharedPart;
}
@Override
public String toString() {
return makeSparseCopy().toString();
}
/** Warning: inefficient; this should not be called often. */
MutableSparseIntSet makeSparseCopy() {
if (privatePart == null) {
if (sharedPart == null) {
return MutableSparseIntSet.makeEmpty();
} else {
return new MutableSparseIntSetFactory().makeCopy(sharedPart);
}
} else {
if (sharedPart == null) {
return MutableSparseIntSet.make(privatePart);
} else {
/* privatePart != null, sharedPart != null */
MutableSparseIntSet result = MutableSparseIntSet.make(privatePart);
result.addAll(sharedPart);
return result;
}
}
}
/** */
BitVectorIntSet makeDenseCopy() {
if (privatePart == null) {
if (sharedPart == null) {
return new BitVectorIntSet();
} else {
return new BitVectorIntSet(sharedPart);
}
} else {
if (sharedPart == null) {
return new BitVectorIntSet(privatePart);
} else {
BitVectorIntSet temp = new BitVectorIntSet(sharedPart);
temp.addAllOblivious(privatePart);
return temp;
}
}
}
public boolean hasSharedPart() {
return sharedPart != null;
}
/**
* @see com.ibm.wala.util.intset.IntSet#containsAny(com.ibm.wala.util.intset.IntSet)
*/
@Override
public boolean containsAny(IntSet set) {
if (set instanceof MutableSharedBitVectorIntSet) {
MutableSharedBitVectorIntSet other = (MutableSharedBitVectorIntSet) set;
if (sharedPart != null) {
// an optimization to make life easier on the underlying
// bitvectorintsets
if (other.sharedPart != null && sharedPart.containsAny(other.sharedPart)) {
return true;
}
if (other.privatePart != null && sharedPart.containsAny(other.privatePart)) {
return true;
}
}
} else {
if (sharedPart != null && sharedPart.containsAny(set)) {
return true;
}
}
if (privatePart != null && privatePart.containsAny(set)) {
return true;
}
return false;
}
@Override
public boolean addAllInIntersection(IntSet other, IntSet filter) {
if (other instanceof MutableSharedBitVectorIntSet) {
return addAllInIntersectionInternal((MutableSharedBitVectorIntSet) other, filter);
}
return addAllInIntersectionGeneral(other, filter);
}
/** */
private boolean addAllInIntersectionGeneral(IntSet other, IntSet filter) {
BitVectorIntSet o = new BitVectorIntSet(other);
o.intersectWith(filter);
return addAll(o);
}
/** */
private boolean addAllInIntersectionInternal(MutableSharedBitVectorIntSet other, IntSet filter) {
if (other.sharedPart == null) {
if (other.privatePart == null) {
return false;
} else {
// other.sharedPart == null, other.privatePart != null
return addAllInIntersectionInternal(other.privatePart, filter);
}
} else {
// other.sharedPart != null
if (sharedPart == other.sharedPart) {
// no need to add in other.sharedPart
if (other.privatePart == null) {
return false;
} else {
return addAllInIntersectionInternal(other.privatePart, filter);
}
} else {
MutableSharedBitVectorIntSet o = new MutableSharedBitVectorIntSet(other);
o.intersectWith(filter);
return addAll(o);
}
}
}
private boolean addAllInIntersectionInternal(SparseIntSet other, IntSet filter) {
if (sharedPart == null) {
if (privatePart == null) {
privatePart = MutableSparseIntSet.make(other);
privatePart.intersectWith(filter);
if (privatePart.isEmpty()) {
privatePart = null;
}
checkOverflow();
return size() > 0;
} else {
// sharedPart == null, privatePart != null
boolean result = privatePart.addAllInIntersection(other, filter);
checkOverflow();
return result;
}
} else {
// sharedPart != null
if (privatePart == null) {
privatePart = MutableSparseIntSet.make(sharedPart);
sharedPart = null;
boolean result = privatePart.addAllInIntersection(other, filter);
checkOverflow();
return result;
} else {
// sharedPart != null, privatePart != null
// note that "other" is likely small
MutableSparseIntSet temp = MutableSparseIntSet.make(other);
temp.intersectWith(filter);
return addAll(temp);
}
}
}
@Override
public void clear() {
privatePart = null;
sharedPart = null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy