26 #include "libadt/vectset.hpp" |
26 #include "libadt/vectset.hpp" |
27 #include "memory/allocation.inline.hpp" |
27 #include "memory/allocation.inline.hpp" |
28 |
28 |
29 // Vector Sets - An Abstract Data Type |
29 // Vector Sets - An Abstract Data Type |
30 |
30 |
31 // %%%%% includes not needed with AVM framework - Ungar |
|
32 // #include "port.hpp" |
|
33 //IMPLEMENTATION |
|
34 // #include "vectset.hpp" |
|
35 |
|
36 // BitsInByte is a lookup table which tells the number of bits that |
31 // BitsInByte is a lookup table which tells the number of bits that |
37 // are in the looked-up number. It is very useful in VectorSet_Size. |
32 // are in the looked-up number. It is very useful in VectorSet_Size. |
38 |
33 |
39 uint8 bitsInByte[256] = { |
34 uint8_t bitsInByte[256] = { |
40 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, |
35 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, |
41 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
36 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
42 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
37 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
43 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
38 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
44 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
39 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
83 //------------------------------slamin----------------------------------------- |
78 //------------------------------slamin----------------------------------------- |
84 // Initialize one set with another. No regard is made to the existing Set. |
79 // Initialize one set with another. No regard is made to the existing Set. |
85 void VectorSet::slamin(const VectorSet& s) |
80 void VectorSet::slamin(const VectorSet& s) |
86 { |
81 { |
87 size = s.size; // Use new size |
82 size = s.size; // Use new size |
88 data = (uint32*)s._set_arena->Amalloc(size*sizeof(uint32)); // Make array of required size |
83 data = (uint32_t*)s._set_arena->Amalloc(size*sizeof(uint32_t)); // Make array of required size |
89 memcpy( data, s.data, size*sizeof(uint32) ); // Fill the array |
84 memcpy( data, s.data, size*sizeof(uint32_t) ); // Fill the array |
90 } |
85 } |
91 |
86 |
92 //------------------------------grow------------------------------------------- |
87 //------------------------------grow------------------------------------------- |
93 // Expand the existing set to a bigger size |
88 // Expand the existing set to a bigger size |
94 void VectorSet::grow( uint newsize ) |
89 void VectorSet::grow( uint newsize ) |
95 { |
90 { |
96 newsize = (newsize+31) >> 5; // Convert to longwords |
91 newsize = (newsize+31) >> 5; // Convert to longwords |
97 uint x = size; |
92 uint x = size; |
98 while( x < newsize ) x <<= 1; |
93 while( x < newsize ) x <<= 1; |
99 data = (uint32 *)_set_arena->Arealloc(data, size*sizeof(uint32), x*sizeof(uint32)); |
94 data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t)); |
100 memset((char *)(data + size), 0, (x - size)*sizeof(uint32)); |
95 memset((char *)(data + size), 0, (x - size)*sizeof(uint32_t)); |
101 size = x; |
96 size = x; |
102 } |
97 } |
103 |
98 |
104 //------------------------------operator<<=------------------------------------ |
99 //------------------------------operator<<=------------------------------------ |
105 // Insert a member into an existing Set. |
100 // Insert a member into an existing Set. |
106 Set &VectorSet::operator <<= (uint elem) |
101 Set &VectorSet::operator <<= (uint elem) |
107 { |
102 { |
108 register uint word = elem >> 5; // Get the longword offset |
103 register uint word = elem >> 5; // Get the longword offset |
109 register uint32 mask = 1L << (elem & 31); // Get bit mask |
104 register uint32_t mask = 1L << (elem & 31); // Get bit mask |
110 |
105 |
111 if( word >= size ) // Need to grow set? |
106 if( word >= size ) // Need to grow set? |
112 grow(elem+1); // Then grow it |
107 grow(elem+1); // Then grow it |
113 data[word] |= mask; // Set new bit |
108 data[word] |= mask; // Set new bit |
114 return *this; |
109 return *this; |
119 Set &VectorSet::operator >>= (uint elem) |
114 Set &VectorSet::operator >>= (uint elem) |
120 { |
115 { |
121 register uint word = elem >> 5; // Get the longword offset |
116 register uint word = elem >> 5; // Get the longword offset |
122 if( word >= size ) // Beyond the last? |
117 if( word >= size ) // Beyond the last? |
123 return *this; // Then it's clear & return clear |
118 return *this; // Then it's clear & return clear |
124 register uint32 mask = 1L << (elem & 31); // Get bit mask |
119 register uint32_t mask = 1L << (elem & 31); // Get bit mask |
125 data[word] &= ~mask; // Clear bit |
120 data[word] &= ~mask; // Clear bit |
126 return *this; |
121 return *this; |
127 } |
122 } |
128 |
123 |
129 //------------------------------operator&=------------------------------------- |
124 //------------------------------operator&=------------------------------------- |
130 // Intersect one set into another. |
125 // Intersect one set into another. |
131 VectorSet &VectorSet::operator &= (const VectorSet &s) |
126 VectorSet &VectorSet::operator &= (const VectorSet &s) |
132 { |
127 { |
133 // NOTE: The intersection is never any larger than the smallest set. |
128 // NOTE: The intersection is never any larger than the smallest set. |
134 if( s.size < size ) size = s.size; // Get smaller size |
129 if( s.size < size ) size = s.size; // Get smaller size |
135 register uint32 *u1 = data; // Pointer to the destination data |
130 register uint32_t *u1 = data; // Pointer to the destination data |
136 register uint32 *u2 = s.data; // Pointer to the source data |
131 register uint32_t *u2 = s.data; // Pointer to the source data |
137 for( uint i=0; i<size; i++) // For data in set |
132 for( uint i=0; i<size; i++) // For data in set |
138 *u1++ &= *u2++; // Copy and AND longwords |
133 *u1++ &= *u2++; // Copy and AND longwords |
139 return *this; // Return set |
134 return *this; // Return set |
140 } |
135 } |
141 |
136 |
150 // Union one set into another. |
145 // Union one set into another. |
151 VectorSet &VectorSet::operator |= (const VectorSet &s) |
146 VectorSet &VectorSet::operator |= (const VectorSet &s) |
152 { |
147 { |
153 // This many words must be unioned |
148 // This many words must be unioned |
154 register uint cnt = ((size<s.size)?size:s.size); |
149 register uint cnt = ((size<s.size)?size:s.size); |
155 register uint32 *u1 = data; // Pointer to the destination data |
150 register uint32_t *u1 = data; // Pointer to the destination data |
156 register uint32 *u2 = s.data; // Pointer to the source data |
151 register uint32_t *u2 = s.data; // Pointer to the source data |
157 for( uint i=0; i<cnt; i++) // Copy and OR the two sets |
152 for( uint i=0; i<cnt; i++) // Copy and OR the two sets |
158 *u1++ |= *u2++; |
153 *u1++ |= *u2++; |
159 if( size < s.size ) { // Is set 2 larger than set 1? |
154 if( size < s.size ) { // Is set 2 larger than set 1? |
160 // Extend result by larger set |
155 // Extend result by larger set |
161 grow(s.size*sizeof(uint32)*8); |
156 grow(s.size*sizeof(uint32_t)*8); |
162 memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32)); |
157 memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32_t)); |
163 } |
158 } |
164 return *this; // Return result set |
159 return *this; // Return result set |
165 } |
160 } |
166 |
161 |
167 //------------------------------operator|=------------------------------------- |
162 //------------------------------operator|=------------------------------------- |
197 // X1 -- A is a subset of B |
192 // X1 -- A is a subset of B |
198 // 0X -- B is not a subset of A |
193 // 0X -- B is not a subset of A |
199 // 1X -- B is a subset of A |
194 // 1X -- B is a subset of A |
200 int VectorSet::compare (const VectorSet &s) const |
195 int VectorSet::compare (const VectorSet &s) const |
201 { |
196 { |
202 register uint32 *u1 = data; // Pointer to the destination data |
197 register uint32_t *u1 = data; // Pointer to the destination data |
203 register uint32 *u2 = s.data; // Pointer to the source data |
198 register uint32_t *u2 = s.data; // Pointer to the source data |
204 register uint32 AnotB = 0, BnotA = 0; |
199 register uint32_t AnotB = 0, BnotA = 0; |
205 // This many words must be unioned |
200 // This many words must be unioned |
206 register uint cnt = ((size<s.size)?size:s.size); |
201 register uint cnt = ((size<s.size)?size:s.size); |
207 |
202 |
208 // Get bits for both sets |
203 // Get bits for both sets |
209 uint i; // Exit value of loop |
204 uint i; // Exit value of loop |
210 for( i=0; i<cnt; i++ ) { // For data in BOTH sets |
205 for( i=0; i<cnt; i++ ) { // For data in BOTH sets |
211 register uint32 A = *u1++; // Data from one guy |
206 register uint32_t A = *u1++; // Data from one guy |
212 register uint32 B = *u2++; // Data from other guy |
207 register uint32_t B = *u2++; // Data from other guy |
213 AnotB |= (A & ~B); // Compute bits in A not B |
208 AnotB |= (A & ~B); // Compute bits in A not B |
214 BnotA |= (B & ~A); // Compute bits in B not A |
209 BnotA |= (B & ~A); // Compute bits in B not A |
215 } |
210 } |
216 |
211 |
217 // Get bits from bigger set |
212 // Get bits from bigger set |
248 // The cast is a virtual function that checks that "set" is a VectorSet. |
243 // The cast is a virtual function that checks that "set" is a VectorSet. |
249 const VectorSet &s = *(set.asVectorSet()); |
244 const VectorSet &s = *(set.asVectorSet()); |
250 |
245 |
251 // NOTE: The intersection is never any larger than the smallest set. |
246 // NOTE: The intersection is never any larger than the smallest set. |
252 register uint small_size = ((size<s.size)?size:s.size); |
247 register uint small_size = ((size<s.size)?size:s.size); |
253 register uint32 *u1 = data; // Pointer to the destination data |
248 register uint32_t *u1 = data; // Pointer to the destination data |
254 register uint32 *u2 = s.data; // Pointer to the source data |
249 register uint32_t *u2 = s.data; // Pointer to the source data |
255 for( uint i=0; i<small_size; i++) // For data in set |
250 for( uint i=0; i<small_size; i++) // For data in set |
256 if( *u1++ & *u2++ ) // If any elements in common |
251 if( *u1++ & *u2++ ) // If any elements in common |
257 return 0; // Then not disjoint |
252 return 0; // Then not disjoint |
258 return 1; // Else disjoint |
253 return 1; // Else disjoint |
259 } |
254 } |
303 { |
298 { |
304 uint i; // Exit value of loop |
299 uint i; // Exit value of loop |
305 for( i=0; i<size; i++ ) |
300 for( i=0; i<size; i++ ) |
306 if( data[i] ) |
301 if( data[i] ) |
307 break; |
302 break; |
308 uint32 word = data[i]; |
303 uint32_t word = data[i]; |
309 int j; // Exit value of loop |
304 int j; // Exit value of loop |
310 for( j= -1; word; j++, word>>=1 ); |
305 for( j= -1; word; j++, word>>=1 ); |
311 return (i<<5)+j; |
306 return (i<<5)+j; |
312 } |
307 } |
313 |
308 |
314 //------------------------------Clear------------------------------------------ |
309 //------------------------------Clear------------------------------------------ |
315 // Clear a set |
310 // Clear a set |
316 void VectorSet::Clear(void) |
311 void VectorSet::Clear(void) |
317 { |
312 { |
318 if( size > 100 ) { // Reclaim storage only if huge |
313 if( size > 100 ) { // Reclaim storage only if huge |
319 FREE_RESOURCE_ARRAY(uint32,data,size); |
314 FREE_RESOURCE_ARRAY(uint32_t,data,size); |
320 size = 2; // Small initial size |
315 size = 2; // Small initial size |
321 data = NEW_RESOURCE_ARRAY(uint32,size); |
316 data = NEW_RESOURCE_ARRAY(uint32_t,size); |
322 } |
317 } |
323 memset( data, 0, size*sizeof(uint32) ); |
318 memset( data, 0, size*sizeof(uint32_t) ); |
324 } |
319 } |
325 |
320 |
326 //------------------------------Size------------------------------------------- |
321 //------------------------------Size------------------------------------------- |
327 // Return number of elements in a Set |
322 // Return number of elements in a Set |
328 uint VectorSet::Size(void) const |
323 uint VectorSet::Size(void) const |
329 { |
324 { |
330 uint sum = 0; // Cumulative size so far. |
325 uint sum = 0; // Cumulative size so far. |
331 uint8 *currByte = (uint8*)data; |
326 uint8_t* currByte = (uint8_t*) data; |
332 for( uint32 i = 0; i < (size<<2); i++) // While have bytes to process |
327 for( uint32_t i = 0; i < (size<<2); i++) // While have bytes to process |
333 sum += bitsInByte[*currByte++]; // Add bits in current byte to size. |
328 sum += bitsInByte[*currByte++]; // Add bits in current byte to size. |
334 return sum; |
329 return sum; |
335 } |
330 } |
336 |
331 |
337 //------------------------------Sort------------------------------------------- |
332 //------------------------------Sort------------------------------------------- |