00001 package ca.mcgill.sable.soot.jimple;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 import ca.mcgill.sable.util.*;
00072
00073 public class ArraySparseSet implements FlowSet
00074 {
00075 static final int DEFAULT_SIZE = 8;
00076
00077 int numElements;
00078 int maxElements;
00079 Object[] elements;
00080
00081 private static class SparseArrayList extends AbstractList
00082 {
00083 private Object[] array;
00084 private int realSize;
00085
00086 public SparseArrayList(Object[] array, int realSize)
00087 {
00088 this.array = array;
00089 this.realSize = realSize;
00090 }
00091
00092 public Object get(int index)
00093 {
00094 return array[index];
00095 }
00096
00097 public Object set(int index, Object element)
00098 {
00099 throw new UnsupportedOperationException();
00100 }
00101
00102 public int size()
00103 {
00104 return realSize;
00105 }
00106
00107 public Object clone()
00108 {
00109 return array.clone();
00110 }
00111
00112 }
00113
00114 public ArraySparseSet()
00115 {
00116 maxElements = DEFAULT_SIZE;
00117 elements = new Object[DEFAULT_SIZE];
00118 numElements = 0;
00119 }
00120 private ArraySparseSet(ArraySparseSet other)
00121 {
00122 numElements = other.numElements;
00123 maxElements = other.maxElements;
00124 elements = (Object[]) other.elements.clone();
00125 }
00126 public void add(Object e)
00127 {
00128
00129 if(numElements == maxElements)
00130 doubleCapacity();
00131
00132
00133 if(!contains(e))
00134 elements[numElements++] = e;
00135 }
00136 public void add(Object obj, FlowSet destFlow)
00137 {
00138 ArraySparseSet dest = (ArraySparseSet) destFlow;
00139
00140 if(this != dest)
00141 copy(dest);
00142
00143 dest.add(obj);
00144 }
00145 public void clear()
00146 {
00147 numElements = 0;
00148 }
00149 public Object clone()
00150 {
00151 return new ArraySparseSet(this);
00152 }
00153 public boolean contains(Object obj)
00154 {
00155 for(int i = 0; i < numElements; i++)
00156 if(elements[i].equals(obj))
00157 return true;
00158
00159 return false;
00160 }
00161 public void copy(FlowSet destFlow)
00162 {
00163 ArraySparseSet dest = (ArraySparseSet) destFlow;
00164
00165 while(dest.maxElements < this.maxElements)
00166 dest.doubleCapacity();
00167
00168 dest.numElements = this.numElements;
00169
00170 System.arraycopy(this.elements, 0,
00171 dest.elements, 0, this.numElements);
00172 }
00173 public void difference(FlowSet otherFlow, FlowSet destFlow)
00174 {
00175 ArraySparseSet other = (ArraySparseSet) otherFlow;
00176 ArraySparseSet dest = (ArraySparseSet) destFlow;
00177 ArraySparseSet workingSet;
00178
00179 if(dest == other || dest == this)
00180 workingSet = new ArraySparseSet();
00181 else {
00182 workingSet = dest;
00183 workingSet.clear();
00184 }
00185
00186 for(int i = 0; i < this.numElements; i++)
00187 {
00188 if(!other.contains(this.elements[i]))
00189 workingSet.add(this.elements[i]);
00190 }
00191
00192 if(workingSet != dest)
00193 workingSet.copy(dest);
00194 }
00195 private void doubleCapacity()
00196 {
00197 int newSize = maxElements * 2;
00198
00199 Object[] newElements = new Object[newSize];
00200
00201 System.arraycopy(elements, 0, newElements, 0, numElements);
00202 elements = newElements;
00203 maxElements = newSize;
00204 }
00205 public boolean equals(Object otherFlow)
00206 {
00207 ArraySparseSet other = (ArraySparseSet) otherFlow;
00208
00209 if(other.numElements != this.numElements)
00210 return false;
00211
00212 int size = this.numElements;
00213
00214
00215 for(int i = 0; i < size; i++)
00216 if(!other.contains(this.elements[i]))
00217 return false;
00218
00219
00220 for(int i = 0; i < size; i++)
00221 if(!this.contains(other.elements[i]))
00222 return false;
00223
00224 return true;
00225 }
00226 public void intersection(FlowSet otherFlow, FlowSet destFlow)
00227 {
00228 ArraySparseSet other = (ArraySparseSet) otherFlow;
00229 ArraySparseSet dest = (ArraySparseSet) destFlow;
00230 ArraySparseSet workingSet;
00231
00232 if(dest == other || dest == this)
00233 workingSet = new ArraySparseSet();
00234 else {
00235 workingSet = dest;
00236 workingSet.clear();
00237 }
00238
00239 for(int i = 0; i < this.numElements; i++)
00240 {
00241 if(other.contains(this.elements[i]))
00242 workingSet.add(this.elements[i]);
00243 }
00244
00245 if(workingSet != dest)
00246 workingSet.copy(dest);
00247 }
00248 public boolean isEmpty()
00249 {
00250 return numElements == 0;
00251 }
00252 public void remove(Object obj, FlowSet destFlow)
00253 {
00254 ArraySparseSet dest = (ArraySparseSet) destFlow;
00255
00256 if(this != dest)
00257 copy(dest);
00258
00259 for(int i = 0; i < this.numElements; i++)
00260 if(dest.elements[i].equals(obj))
00261 {
00262 dest.removeElementAt(i);
00263 break;
00264 }
00265 }
00266 private void removeElementAt(int index)
00267 {
00268
00269 if(index == numElements - 1)
00270 {
00271 numElements--;
00272 return;
00273 }
00274
00275
00276 System.arraycopy(elements, index + 1, elements, index, numElements - (index + 1));
00277 numElements--;
00278 }
00279 public int size()
00280 {
00281 return numElements;
00282 }
00283 public List toList()
00284 {
00285 return new SparseArrayList(elements, numElements);
00286 }
00287 public String toString()
00288 {
00289 StringBuffer buffer = new StringBuffer("{");
00290 Iterator it = toList().iterator();
00291
00292 if(it.hasNext())
00293 {
00294 buffer.append(it.next());
00295
00296 while(it.hasNext())
00297 {
00298 buffer.append(", " + it.next());
00299 }
00300 }
00301
00302 buffer.append("}");
00303
00304 return buffer.toString();
00305 }
00306 public void union(FlowSet otherFlow, FlowSet destFlow)
00307 {
00308 ArraySparseSet other = (ArraySparseSet) otherFlow;
00309 ArraySparseSet dest = (ArraySparseSet) destFlow;
00310
00311
00312 if(dest == other)
00313 {
00314 for(int i = 0; i < this.numElements; i++)
00315 dest.add(this.elements[i]);
00316 }
00317
00318
00319 else {
00320 if(this != dest)
00321 copy(dest);
00322
00323 for(int i = 0; i < other.numElements; i++)
00324 dest.add(other.elements[i]);
00325 }
00326 }
00327 }