00001 /* 00002 00003 Copyright (c) 2003, Cornell University 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are met: 00008 00009 - Redistributions of source code must retain the above copyright notice, 00010 this list of conditions and the following disclaimer. 00011 - Redistributions in binary form must reproduce the above copyright 00012 notice, this list of conditions and the following disclaimer in the 00013 documentation and/or other materials provided with the distribution. 00014 - Neither the name of Cornell University nor the names of its 00015 contributors may be used to endorse or promote products derived from 00016 this software without specific prior written permission. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00028 THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 */ 00031 00032 00033 ///////////////////////////////////////////////////////////////////// 00034 /// 00035 /// BaseBitmap.cpp 00036 /// 00037 ///////////////////////////////////////////////////////////////////// 00038 00039 #include "BaseBitmap.h" 00040 #include <limits.h> 00041 00042 ///////////////////////////////////////////////////////////////////// 00043 /// @addtogroup BitmapProcessing 00044 /** @{ */ 00045 00046 #define BYTE_COUNT (sizeof(unsigned int) / sizeof(unsigned char)) 00047 00048 ///////////////////////////////////////////////////////////////////// 00049 /// Allocate the memory for the BaseBitmap 00050 /// 00051 /// @param numBits number of bits in the BaseBitmap 00052 ///////////////////////////////////////////////////////////////////// 00053 BaseBitmap::BaseBitmap(int numBits) { 00054 // Convert bitsize to number of ints 00055 _size = (numBits / 32) + 1; 00056 _memory = new unsigned int[_size]; 00057 _count = 0; 00058 00059 // fill BaseBitmap with zeroes 00060 for (int index = 0; index < _size; index++) 00061 _memory[index] = 0; 00062 } 00063 00064 ///////////////////////////////////////////////////////////////////// 00065 /// Copy constructor 00066 /// 00067 /// @param bitmapToCopy BaseBitmap to copy 00068 ///////////////////////////////////////////////////////////////////// 00069 BaseBitmap::BaseBitmap(BaseBitmap &bitmapToCopy) { 00070 // Copy information from source bitmap 00071 _size = bitmapToCopy._size; 00072 _memory = new unsigned int[ _size ]; 00073 _count = bitmapToCopy._count; 00074 00075 for (int byteIndex = 0; byteIndex < bitmapToCopy._size; byteIndex++) 00076 _memory[byteIndex] = bitmapToCopy._memory[byteIndex]; 00077 } 00078 00079 ///////////////////////////////////////////////////////////////////// 00080 /// Fill the BaseBitmap with random data 00081 /// 00082 /// @param prob probability of a bit being set to 1 00083 ///////////////////////////////////////////////////////////////////// 00084 void BaseBitmap::FillRand(double prob) { 00085 unsigned int randy; 00086 00087 for (int byteIndex = 0; byteIndex < _size; byteIndex++) { 00088 randy = 0; 00089 for (int bitIndex = 0; bitIndex < 32; bitIndex++) { 00090 // Fill bit with 1 when below probability prob 00091 if ((rand() / (float)RAND_MAX) < prob) 00092 randy = randy + BitTable[bitIndex]; 00093 } 00094 00095 _memory[byteIndex] = randy; 00096 } 00097 } 00098 00099 ///////////////////////////////////////////////////////////////////// 00100 /// Fill the BaseBitmap with ones 00101 ///////////////////////////////////////////////////////////////////// 00102 void BaseBitmap::FillOnes() { 00103 for (int byteIndex = 0; byteIndex < _size; byteIndex++) 00104 _memory[byteIndex] = UINT_MAX; 00105 } 00106 00107 ///////////////////////////////////////////////////////////////////// 00108 /// Count the ones in the bitmap 00109 /// 00110 /// @param CountCounts a counter of counts (for debugging) 00111 /// @return the count of ones 00112 ///////////////////////////////////////////////////////////////////// 00113 int BaseBitmap::Count(int &CountCounts) { 00114 int final = 0; 00115 unsigned char *currentIndex; 00116 for (int byteIndex = 0; byteIndex < _size; byteIndex++) { 00117 currentIndex = (unsigned char *) & _memory[byteIndex]; 00118 00119 // Count the 4 chars (1 int = 4 bytes/chars) 00120 // count 1s by dividing into chars and using a lookup table 00121 final += CountTable[*currentIndex]; 00122 currentIndex++; 00123 final += CountTable[*currentIndex]; 00124 currentIndex++; 00125 final += CountTable[*currentIndex]; 00126 currentIndex++; 00127 final += CountTable[*currentIndex]; 00128 } 00129 00130 CountCounts++; 00131 00132 // set the count for the BaseBitmap 00133 _count = final; 00134 return final; 00135 } 00136 00137 ///////////////////////////////////////////////////////////////////// 00138 /// Bitwise OR 2 bitmaps and store the result 00139 /// 00140 /// @param B1 the first Bitmap 00141 /// @param B2 the second Bitmap 00142 ///////////////////////////////////////////////////////////////////// 00143 void BaseBitmap::Or(const BaseBitmap &B1, const BaseBitmap &B2) { 00144 unsigned int *b1ptr, *b2ptr; 00145 b1ptr = B1._memory; 00146 b2ptr = B2._memory; 00147 00148 // for each INT in the bitmaps 00149 for (int byteIndex = 0; byteIndex < B1._size; byteIndex++) { 00150 /// Bitwise OR the int 00151 _memory[byteIndex] = (*b1ptr) | (*b2ptr); 00152 b1ptr++; 00153 b2ptr++; 00154 } 00155 00156 // Update the count (B1 and B2 are mutually exclusive) 00157 _count = B1._count + B2._count; 00158 } 00159 00160 ///////////////////////////////////////////////////////////////////// 00161 /// Bitwise AND 2 bitmaps and store the result 00162 /// 00163 /// @param B1 the first Bitmap 00164 /// @param B2 the second Bitmap 00165 /// @param CountAnds [output] counter for # of ANDs (for debugging) 00166 ///////////////////////////////////////////////////////////////////// 00167 void BaseBitmap::AndOnly( 00168 const BaseBitmap &B1, 00169 const BaseBitmap &B2, 00170 int &CountAnds) { 00171 00172 CountAnds++; 00173 unsigned int *b1ptr, *b2ptr; 00174 00175 // AND the bitmaps 00176 00177 b1ptr = B1._memory; 00178 b2ptr = B2._memory; 00179 00180 for (int byteIndex = 0; byteIndex < B1._size; byteIndex++) { 00181 // and each int bitwise 00182 _memory[byteIndex] = (*b1ptr) & (*b2ptr); 00183 b1ptr++; 00184 b2ptr++; 00185 } 00186 } 00187 00188 ///////////////////////////////////////////////////////////////////// 00189 /// Bitwise AND 2 bitmaps and the negation and store the result 00190 /// 00191 /// @param B1 the first Bitmap 00192 /// @param B2 the second Bitmap 00193 /// @param CountAnds [output] counter for # of ANDs (for debugging) 00194 ///////////////////////////////////////////////////////////////////// 00195 void BaseBitmap::NotAndOnly( 00196 const BaseBitmap &B1, 00197 const BaseBitmap &B2, 00198 int &CountAnds) { 00199 00200 CountAnds++; 00201 unsigned int *b1ptr, *b2ptr; 00202 00203 // AND the small bitmaps 00204 00205 b1ptr = B1._memory; 00206 b2ptr = B2._memory; 00207 00208 for (int byteIndex = 0; byteIndex < B1._size; byteIndex++) { 00209 // and each int bitwise 00210 _memory[byteIndex] = (*b1ptr) & ~(*b2ptr); 00211 b1ptr++; 00212 b2ptr++; 00213 } 00214 } 00215 00216 ///////////////////////////////////////////////////////////////////// 00217 /// Determine whether this bitmap is a superset of the parameter. 00218 /// NOTE: Assumes the set of bitmaps is lexicographically ordered. 00219 /// 00220 /// @param subset bitmap to check for a superset relation 00221 /// @return True if this bitmap is a superset of the 00222 /// parameter bitmap (this bitmap has a 1 in ALL 00223 /// positions that parameter bitmap does ) 00224 ///////////////////////////////////////////////////////////////////// 00225 bool BaseBitmap::Superset(const BaseBitmap *subset) { 00226 // No need to check for superset when the count is too small 00227 if (_count <= subset->_count) { 00228 return false; 00229 } 00230 00231 // Start at the end of the bitmap 00232 // Leads to fewer bitwise ANDs 00233 unsigned int *b1ptr, *b2ptr; 00234 b1ptr = &_memory[_size - 1]; 00235 b2ptr = &subset->_memory[subset->_size - 1]; 00236 00237 // for each INT in the bitmaps 00238 for (int byteIndex = _size - 1; byteIndex >= 0; byteIndex--) { 00239 // Andy++; 00240 // bitwise AND them 00241 unsigned int andResult = (*b1ptr) & (*b2ptr); 00242 00243 // if not a subset 00244 if (andResult != *b2ptr) 00245 return false; 00246 00247 b1ptr--; 00248 b2ptr--; 00249 } 00250 00251 return true; 00252 } 00253 00254 ///////////////////////////////////////////////////////////////////// 00255 /// Determine whether this bitmap is a superset of the parameter or equal to it 00256 /// 00257 /// @param subset bitmap to check for a superseteq relation 00258 /// @return True if this bitmap is a superset of the 00259 /// parameter bitmap (this bitmap has a 1 in ALL 00260 /// positions that parameter bitmap does ) 00261 ///////////////////////////////////////////////////////////////////// 00262 bool BaseBitmap::SupersetEq(const BaseBitmap *subset) { 00263 // No need to check for superset when the count is too small 00264 if (_count < subset->_count) { 00265 return false; 00266 } 00267 00268 // Start at the end of the bitmap 00269 // Leads to fewer bitwise ANDs 00270 unsigned int *b1ptr, *b2ptr; 00271 b1ptr = &_memory[_size - 1]; 00272 b2ptr = &subset->_memory[subset->_size - 1]; 00273 00274 // for each INT in the bitmaps 00275 for (int byteIndex = _size - 1; byteIndex >= 0; byteIndex--) { 00276 // Andy++; 00277 // bitwise AND them 00278 unsigned int andResult = (*b1ptr) & (*b2ptr); 00279 00280 // if not a subset 00281 if (andResult != *b2ptr) 00282 return false; 00283 00284 b1ptr--; 00285 b2ptr--; 00286 } 00287 00288 return true; 00289 } 00290 00291 /** @} */