KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > toolkits > scalar > ArrayPackedSet


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-1999 Raja Vallee-Rai
3  * updated 2002 Florian Loitsch
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */

20
21 /*
22  * Modified by the Sable Research Group and others 1997-1999.
23  * See the 'credits' file distributed with Soot for the complete list of
24  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
25  */

26
27
28 package soot.toolkits.scalar;
29
30 import soot.util.*;
31 import java.util.*;
32
33
34 /**
35  * Reference implementation for a BoundedFlowSet. Items are stored in an Array.
36  */

37 public class ArrayPackedSet extends AbstractBoundedFlowSet
38 {
39     ObjectIntMapper map;
40     int[] bits;
41
42     public ArrayPackedSet(FlowUniverse universe) {
43         this(new ObjectIntMapper(universe));
44     }
45
46     ArrayPackedSet(ObjectIntMapper map)
47     {
48         //int size = universe.getSize();
49

50         //int numWords = size / 32 + (((size % 32) != 0) ? 1 : 0);
51

52         this(map, new int[map.size() / 32 + (((map.size() % 32) != 0) ? 1 : 0)]);
53     }
54     
55     ArrayPackedSet(ObjectIntMapper map, int[] bits)
56     {
57         this.map = map;
58         this.bits = (int[]) bits.clone();
59     }
60
61     /** Returns true if flowSet is the same type of flow set as this. */
62     private boolean sameType(Object JavaDoc flowSet)
63     {
64         return (flowSet instanceof ArrayPackedSet &&
65                 ((ArrayPackedSet)flowSet).map == map);
66     }
67
68     public Object JavaDoc clone()
69     {
70         return new ArrayPackedSet(map, bits);
71     }
72
73     public Object JavaDoc emptySet()
74     {
75         return new ArrayPackedSet(map);
76     }
77
78     public int size()
79     {
80         int count = 0;
81
82         for(int i = 0; i < bits.length; i++)
83         {
84             int word = bits[i];
85
86             for(int j = 0; j < 32; j++)
87                 if((word & (1 << j)) != 0)
88                     count++;
89         }
90
91         return count;
92     }
93
94     public boolean isEmpty()
95     {
96         for(int i = 0; i < bits.length; i++)
97             if(bits[i] != 0)
98                 return false;
99
100         return true;
101     }
102
103
104     public void clear()
105     {
106         for(int i = 0; i < bits.length; i++)
107             bits[i] = 0;
108     }
109
110
111     public List toList(int low, int high)
112     {
113         List elements = new ArrayList();
114
115         int startWord = low / 32,
116             startBit = low % 32;
117
118         int endWord = high / 32,
119             endBit = high % 32;
120
121         if(low > high)
122             return elements;
123
124         // Do the first word
125
{
126             int word = bits[startWord];
127
128             int offset = startWord * 32;
129             int lastBit = (startWord != endWord) ? 32 : (endBit + 1);
130
131             for(int j = startBit; j < lastBit; j++)
132             {
133                 if((word & (1 << j)) != 0)
134                     elements.add(map.getObject(offset + j));
135             }
136         }
137
138         // Do the in between ones
139
if(startWord != endWord && startWord + 1 != endWord)
140             {
141                 for(int i = startWord + 1; i < endWord; i++)
142                 {
143                     int word = bits[i];
144                     int offset = i * 32;
145
146                     for(int j = 0; j < 32; j++)
147                     {
148                         if((word & (1 << j)) != 0)
149                             elements.add(map.getObject(offset + j));
150                     }
151                 }
152             }
153
154         // Do the last one
155
if(startWord != endWord)
156             {
157                 int word = bits[endWord];
158                 int offset = endWord * 32;
159                 int lastBit = endBit + 1;
160
161                 for(int j = 0; j < lastBit; j++)
162                 {
163                     if((word & (1 << j)) != 0)
164                         elements.add(map.getObject(offset + j));
165                 }
166             }
167
168         return elements;
169     }
170
171
172     public List toList()
173     {
174         List elements = new ArrayList();
175
176         for(int i = 0; i < bits.length; i++)
177         {
178             int word = bits[i];
179             int offset = i * 32;
180
181             for(int j = 0; j < 32; j++)
182                 if((word & (1 << j)) != 0)
183                     elements.add(map.getObject(offset + j));
184         }
185
186         return elements;
187     }
188
189     public void add(Object JavaDoc obj)
190     {
191         int bitNum = map.getInt(obj);
192
193         bits[bitNum / 32] |= 1 << (bitNum % 32);
194     }
195
196     public void complement(FlowSet destFlow)
197     {
198       if (sameType(destFlow)) {
199         ArrayPackedSet dest = (ArrayPackedSet) destFlow;
200
201         for(int i = 0; i < bits.length; i++)
202             dest.bits[i] = ~(this.bits[i]);
203             
204         // Clear the bits which are outside of this universe
205
if(bits.length >= 1)
206             {
207                 int lastValidBitCount = map.size() % 32;
208                 
209                 if(lastValidBitCount != 0)
210                     dest.bits[bits.length - 1] &= ~(0xFFFFFFFF << lastValidBitCount);
211             }
212       } else
213         super.complement(destFlow);
214     }
215
216     public void remove(Object JavaDoc obj)
217     {
218         int bitNum = map.getInt(obj);
219
220         bits[bitNum / 32] &= ~(1 << (bitNum % 32));
221     }
222
223     public void union(FlowSet otherFlow, FlowSet destFlow)
224     {
225       if (sameType(otherFlow) &&
226           sameType(destFlow)) {
227         ArrayPackedSet other = (ArrayPackedSet) otherFlow;
228         ArrayPackedSet dest = (ArrayPackedSet) destFlow;
229
230         if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
231             throw new RuntimeException JavaDoc("Incompatible other set for union");
232
233         for(int i = 0; i < bits.length; i++)
234             dest.bits[i] = this.bits[i] | other.bits[i];
235       } else
236         super.union(otherFlow, destFlow);
237     }
238
239     public void difference(FlowSet otherFlow, FlowSet destFlow)
240     {
241       if (sameType(otherFlow) &&
242           sameType(destFlow)) {
243         ArrayPackedSet other = (ArrayPackedSet) otherFlow;
244         ArrayPackedSet dest = (ArrayPackedSet) destFlow;
245
246         if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
247             throw new RuntimeException JavaDoc("Incompatible other set for union");
248             
249         for(int i = 0; i < bits.length; i++)
250             dest.bits[i] = this.bits[i] & ~other.bits[i];
251       } else
252         super.difference(otherFlow, destFlow);
253     }
254     
255     public void intersection(FlowSet otherFlow, FlowSet destFlow)
256     {
257       if (sameType(otherFlow) &&
258           sameType(destFlow)) {
259         ArrayPackedSet other = (ArrayPackedSet) otherFlow;
260         ArrayPackedSet dest = (ArrayPackedSet) destFlow;
261
262         if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
263             throw new RuntimeException JavaDoc("Incompatible other set for union");
264
265         for(int i = 0; i < bits.length; i++)
266             dest.bits[i] = this.bits[i] & other.bits[i];
267       } else
268         super.intersection(otherFlow, destFlow);
269     }
270
271   /** Returns true, if the object is in the set.
272    */

273     public boolean contains(Object JavaDoc obj)
274     {
275       /* check if the object is in the map, direct call of map.getInt will
276        * add the object into the map.
277        */

278         if (!map.contains(obj)) return false;
279
280         int bitNum = map.getInt(obj);
281
282         return (bits[bitNum / 32] & (1 << (bitNum % 32))) != 0;
283     }
284
285     public boolean equals(Object JavaDoc otherFlow)
286     {
287       if (sameType(otherFlow)) {
288         ArrayPackedSet other = (ArrayPackedSet) otherFlow;
289
290         for(int i = 0; i < bits.length; i++)
291             if(this.bits[i] != other.bits[i])
292                 return false;
293
294         return true;
295       } else
296         return super.equals(otherFlow);
297     }
298
299     public void copy(FlowSet destFlow)
300     {
301       if (sameType(destFlow)) {
302         ArrayPackedSet dest = (ArrayPackedSet) destFlow;
303
304         for(int i = 0; i < bits.length; i++)
305             dest.bits[i] = this.bits[i];
306       } else
307         super.copy(destFlow);
308     }
309
310 }
311
312
Popular Tags