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:
dolby-oss 2007-01-11 04:03:21 +00:00
parent 429403c321
commit 1b14e57da9
4 changed files with 188 additions and 19 deletions

View File

@ -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;
}
}
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;
}
/*