more optimization of SemiSparseMutableIntSets
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@553 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
429403c321
commit
1b14e57da9
|
@ -84,6 +84,7 @@ public class IntSetUtil {
|
|||
public static IntSet diff(IntSet A, IntSet B) {
|
||||
return diff(A, B, IntSetUtil.getDefaultIntSetFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the asymmetric difference of two sets, a \ b.
|
||||
*
|
||||
|
@ -99,6 +100,15 @@ public class IntSetUtil {
|
|||
Trace.println("call SparseIntSet.diff");
|
||||
}
|
||||
return SparseIntSet.diff((SparseIntSet) A, (SparseIntSet) B);
|
||||
|
||||
} else if (A instanceof SemiSparseMutableIntSet &&
|
||||
B instanceof SemiSparseMutableIntSet)
|
||||
{
|
||||
if (DEBUG) {
|
||||
Trace.println("call SemiSparseMutableIntSet.diff");
|
||||
}
|
||||
return SemiSparseMutableIntSet.diff((SemiSparseMutableIntSet) A,
|
||||
(SemiSparseMutableIntSet) B);
|
||||
} else {
|
||||
// TODO: this is slow ... optimize please.
|
||||
MutableIntSet result = factory.makeCopy(A);
|
||||
|
@ -117,6 +127,36 @@ public class IntSetUtil {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two sets, i.e. a = a \ b.
|
||||
*
|
||||
* @param A
|
||||
* @param B
|
||||
*/
|
||||
public static MutableIntSet removeAll(MutableIntSet A, IntSet B) {
|
||||
if (A instanceof SemiSparseMutableIntSet &&
|
||||
B instanceof SemiSparseMutableIntSet)
|
||||
{
|
||||
if (DEBUG) {
|
||||
Trace.println("call SemiSparseMutableIntSet.removeAll");
|
||||
}
|
||||
return
|
||||
((SemiSparseMutableIntSet) A).removeAll((SemiSparseMutableIntSet) B);
|
||||
} else {
|
||||
for (IntIterator it = B.intIterator(); it.hasNext();) {
|
||||
int I = it.next();
|
||||
A.remove(I);
|
||||
if (DEBUG) {
|
||||
Trace.println("removed " + I + " now is " + A);
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
Trace.println("return " + A);
|
||||
}
|
||||
return A;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,4 +206,4 @@ public class IntSetUtil {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -472,4 +472,11 @@ public class MutableSparseIntSet extends SparseIntSet implements MutableIntSet {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static MutableSparseIntSet
|
||||
diff(MutableSparseIntSet A, MutableSparseIntSet B)
|
||||
{
|
||||
return new MutableSparseIntSet(diffInternal(A, B));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,18 +16,29 @@ import com.ibm.wala.util.collections.EmptyIntIterator;
|
|||
public class SemiSparseMutableIntSet implements MutableIntSet {
|
||||
private static final int SPARSE_INSERT_THRESHOLD = 11;
|
||||
|
||||
private MutableSparseIntSet sparsePart = new MutableSparseIntSet();
|
||||
private MutableSparseIntSet sparsePart;
|
||||
|
||||
private OffsetBitVector densePart = null;
|
||||
|
||||
private int sparseInsertCount = 0;
|
||||
|
||||
public SemiSparseMutableIntSet() {
|
||||
// this space intentionally left blank
|
||||
this(new MutableSparseIntSet());
|
||||
}
|
||||
|
||||
private SemiSparseMutableIntSet(MutableSparseIntSet sparsePart) {
|
||||
this.sparsePart = sparsePart;
|
||||
}
|
||||
|
||||
private SemiSparseMutableIntSet(MutableSparseIntSet sparsePart,
|
||||
OffsetBitVector densePart)
|
||||
{
|
||||
this.sparsePart = sparsePart;
|
||||
this.densePart = densePart;
|
||||
}
|
||||
|
||||
public SemiSparseMutableIntSet(SemiSparseMutableIntSet set) {
|
||||
copySet(set);
|
||||
copySet(set);
|
||||
}
|
||||
|
||||
private void fixAfterSparseInsert() {
|
||||
|
@ -240,8 +251,7 @@ public class SemiSparseMutableIntSet implements MutableIntSet {
|
|||
i = next;
|
||||
return next;
|
||||
}
|
||||
}
|
||||
;
|
||||
};
|
||||
|
||||
if (sparsePart.isEmpty()) {
|
||||
if (densePart == null || densePart.isZero()) {
|
||||
|
@ -470,7 +480,7 @@ public class SemiSparseMutableIntSet implements MutableIntSet {
|
|||
public boolean remove(int i) {
|
||||
if (densePart != null && densePart.get(i)) {
|
||||
densePart.clear(i);
|
||||
if (densePart.populationCount() == 0) {
|
||||
if (densePart.nextSetBit(0) == -1) {
|
||||
densePart = null;
|
||||
}
|
||||
return true;
|
||||
|
@ -515,11 +525,117 @@ public class SemiSparseMutableIntSet implements MutableIntSet {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer("[");
|
||||
if (densePart != null) {
|
||||
sb.append("densePart: ").append(densePart.toString()).append(" ");
|
||||
}
|
||||
sb.append("sparsePart: ").append(sparsePart.toString()).append("]");
|
||||
return sb.toString();
|
||||
StringBuffer sb = new StringBuffer("[");
|
||||
if (densePart != null) {
|
||||
sb.append("densePart: ").append(densePart.toString()).append(" ");
|
||||
}
|
||||
sb.append("sparsePart: ").append(sparsePart.toString()).append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public SemiSparseMutableIntSet removeAll(SemiSparseMutableIntSet B)
|
||||
{
|
||||
if (densePart == null) {
|
||||
|
||||
if (B.densePart == null) {
|
||||
sparsePart = MutableSparseIntSet.diff(sparsePart, B.sparsePart);
|
||||
|
||||
} else {
|
||||
MutableSparseIntSet C =
|
||||
MutableSparseIntSet.diff(sparsePart, B.sparsePart);
|
||||
for(IntIterator bits = sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
int bit = bits.next();
|
||||
if (B.densePart.get(bit)) {
|
||||
C.remove(bit);
|
||||
}
|
||||
}
|
||||
|
||||
sparsePart = C;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (B.densePart == null) {
|
||||
for(IntIterator bits = B.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
densePart.clear(bits.next());
|
||||
}
|
||||
|
||||
sparsePart = MutableSparseIntSet.diff(sparsePart, B.sparsePart);
|
||||
|
||||
} else {
|
||||
densePart.andNot(B.densePart);
|
||||
for(IntIterator bits = B.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
densePart.clear(bits.next());
|
||||
}
|
||||
|
||||
MutableSparseIntSet C =
|
||||
MutableSparseIntSet.diff(sparsePart, B.sparsePart);
|
||||
for(IntIterator bits = sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
int bit = bits.next();
|
||||
if (B.densePart.get(bit)) {
|
||||
C.remove(bit);
|
||||
}
|
||||
}
|
||||
|
||||
sparsePart = C;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static SemiSparseMutableIntSet
|
||||
diff(SemiSparseMutableIntSet A, SemiSparseMutableIntSet B)
|
||||
{
|
||||
if (A.densePart == null) {
|
||||
|
||||
if (B.densePart == null) {
|
||||
return
|
||||
new SemiSparseMutableIntSet(
|
||||
MutableSparseIntSet.diff(A.sparsePart, B.sparsePart));
|
||||
|
||||
} else {
|
||||
MutableSparseIntSet C =
|
||||
MutableSparseIntSet.diff(A.sparsePart, B.sparsePart);
|
||||
for(IntIterator bits = A.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
int bit = bits.next();
|
||||
if (B.densePart.get(bit)) {
|
||||
C.remove(bit);
|
||||
}
|
||||
}
|
||||
|
||||
return new SemiSparseMutableIntSet(C);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (B.densePart == null) {
|
||||
OffsetBitVector newDensePart = new OffsetBitVector(A.densePart);
|
||||
for(IntIterator bits = B.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
newDensePart.clear(bits.next());
|
||||
}
|
||||
|
||||
return new SemiSparseMutableIntSet(
|
||||
MutableSparseIntSet.diff(A.sparsePart, B.sparsePart),
|
||||
newDensePart);
|
||||
|
||||
} else {
|
||||
OffsetBitVector newDensePart = new OffsetBitVector(A.densePart);
|
||||
newDensePart.andNot(B.densePart);
|
||||
for(IntIterator bits = B.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
newDensePart.clear(bits.next());
|
||||
}
|
||||
|
||||
MutableSparseIntSet C =
|
||||
MutableSparseIntSet.diff(A.sparsePart, B.sparsePart);
|
||||
for(IntIterator bits = A.sparsePart.intIterator(); bits.hasNext(); ) {
|
||||
int bit = bits.next();
|
||||
if (B.densePart.get(bit)) {
|
||||
C.remove(bit);
|
||||
}
|
||||
}
|
||||
|
||||
return new SemiSparseMutableIntSet(C, newDensePart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -240,6 +240,10 @@ public class SparseIntSet implements IntSet {
|
|||
*
|
||||
*/
|
||||
public static SparseIntSet diff(SparseIntSet A, SparseIntSet B) {
|
||||
return new SparseIntSet(diffInternal(A, B));
|
||||
}
|
||||
|
||||
public static int[] diffInternal(SparseIntSet A, SparseIntSet B) {
|
||||
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(A != null);
|
||||
|
@ -247,13 +251,15 @@ public class SparseIntSet implements IntSet {
|
|||
}
|
||||
|
||||
if (A.isEmpty()) {
|
||||
return new SparseIntSet(0);
|
||||
return new int[0];
|
||||
} else if (B.isEmpty()) {
|
||||
return new SparseIntSet(A);
|
||||
int[] newElts = new int[ A.elements.length ];
|
||||
System.arraycopy(A.elements, 0, newElts, 0, A.elements.length);
|
||||
return newElts;
|
||||
} else if (A.equals(B)) {
|
||||
return new SparseIntSet(0);
|
||||
return new int[0];
|
||||
} else if (A.sameValue(B)) {
|
||||
return new SparseIntSet(0);
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
int[] ar = A.elements;
|
||||
|
@ -291,7 +297,7 @@ public class SparseIntSet implements IntSet {
|
|||
// now compact cr to 'just enough'
|
||||
ar = new int[ci];
|
||||
System.arraycopy(cr, 0, ar, 0, ci); // ar := cr
|
||||
return new SparseIntSet(ar);
|
||||
return ar;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue