00001 /* 00002 00003 Copyright (c) 2004, 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 /// Bitmap64.cpp 00036 /// 00037 ///////////////////////////////////////////////////////////////////// 00038 00039 #include <limits.h> 00040 #include <stdio.h> 00041 #include "Bitmap64.h" 00042 00043 const int Bitmap64::_lookupTableSize = 0x10000; 00044 00045 int Bitmap64::_countOr = 0; 00046 int Bitmap64::_countAnd = 0; 00047 int Bitmap64::_countCount = 0; 00048 int Bitmap64::_countCreateSBitmap = 0; 00049 int Bitmap64::_countCreateCBitmap = 0; 00050 int* Bitmap64::_sBitmapLookupTable = 0; 00051 int* Bitmap64::_cBitmapLookupTable = 0; 00052 00053 #define DEBUG_BITMAP64COUNT 00054 00055 00056 ///////////////////////////////////////////////////////////////////// 00057 /// Initialize the counting tables 00058 ///////////////////////////////////////////////////////////////////// 00059 void Bitmap64::Init() 00060 { 00061 int i; 00062 00063 // ------ initialize sBitmapLookupTable ----------------------------- 00064 _sBitmapLookupTable = new int[_lookupTableSize]; 00065 memset(_sBitmapLookupTable, 0, SIZE_INT*_lookupTableSize); 00066 00067 _sBitmapLookupTable[0] = 0; 00068 _sBitmapLookupTable[1] = 0; 00069 00070 int curValue = 0; 00071 int curIndex = 1; 00072 for (i = 2; i < _lookupTableSize; i++) 00073 { 00074 if (i % curIndex == 0) 00075 { 00076 curValue = curValue + curIndex; 00077 curIndex *= 2; 00078 } 00079 _sBitmapLookupTable[i] = curValue; 00080 } 00081 00082 // ------ initialize cBitmapLookupTable ----------------------------- 00083 _cBitmapLookupTable = new int[_lookupTableSize]; 00084 memset(_cBitmapLookupTable, 0, SIZE_UINT*_lookupTableSize); 00085 00086 _cBitmapLookupTable[0] = 0; 00087 _cBitmapLookupTable[1] = 1; 00088 00089 curValue = 1; 00090 curIndex = 1; 00091 for (i = 2; i < _lookupTableSize; i++) 00092 { 00093 if (i % curIndex == 0) 00094 { 00095 curIndex *= 2; 00096 curValue = curValue + curIndex; 00097 } 00098 _cBitmapLookupTable[i] = curValue; 00099 } 00100 } 00101 00102 ///////////////////////////////////////////////////////////////////// 00103 /// deallocate counting tables 00104 ///////////////////////////////////////////////////////////////////// 00105 void Bitmap64::Destroy() 00106 { 00107 if (_sBitmapLookupTable != 0) 00108 delete [] _sBitmapLookupTable; 00109 00110 if (_cBitmapLookupTable != 0) 00111 delete [] _cBitmapLookupTable; 00112 } 00113 00114 ///////////////////////////////////////////////////////////////////// 00115 /// Bitwise OR 2 bitmap64s and store the result 00116 /// 00117 /// @param b1 the first Bitmap64 00118 /// @param b2 the second Bitmap64 00119 ///////////////////////////////////////////////////////////////////// 00120 void Bitmap64::Or(const Bitmap64 &b1, const Bitmap64 &b2) 00121 { 00122 #ifdef DEBUG_BITMAP64COUNT 00123 _countOr++; 00124 #endif 00125 00126 // OR each int bitwise 00127 for (int i = 0; i < b1._memSizeInt; i++) 00128 _memory[i] = b1._memory[i] | b2._memory[i]; 00129 } 00130 00131 00132 ///////////////////////////////////////////////////////////////////// 00133 /// Bitwise AND 2 bitmap64s and store the result 00134 /// 00135 /// @param b1 the first Bitmap64 00136 /// @param b2 the second Bitmap64 00137 ///////////////////////////////////////////////////////////////////// 00138 void Bitmap64::And(const Bitmap64 &b1, const Bitmap64 &b2) 00139 { 00140 #ifdef DEBUG_BITMAP64COUNT 00141 _countAnd++; 00142 #endif 00143 00144 // AND each int bitwise 00145 for (int i = 0; i < b1._memSizeInt; i++) 00146 _memory[i] = b1._memory[i] & b2._memory[i]; 00147 } 00148 00149 00150 ///////////////////////////////////////////////////////////////////// 00151 /// find the support of this bitmap64 in *number of customers* 00152 /// 00153 /// @return the number of customers that have some bit set among their 64 bits 00154 ///////////////////////////////////////////////////////////////////// 00155 int Bitmap64::Count() 00156 { 00157 00158 #ifdef DEBUG_BITMAP64COUNT 00159 _countCount++; 00160 #endif 00161 00162 int support = 0; 00163 00164 // Go through each group of 2 ints 00165 assert (0 == (_memSizeInt % 2)); 00166 00167 for (int i = 0; i < _memSizeInt; i += 2) 00168 if ((_memory[i] > 0) || (_memory[i + 1] > 0)) 00169 support++; 00170 00171 return support; 00172 } 00173 00174 ///////////////////////////////////////////////////////////////////// 00175 /// Create a s-bitmap from an i-bitmap 00176 /// <p> 00177 /// Idea : Again, we go thru each element of _memory. For each element, 00178 /// if it is greater than 0, we look up the transformation table 00179 /// (postProcessTable) to find the corresponding value for the s-bitmap, 00180 /// and set the remaining SHORTs of the current custom to USHRT_MAX 00181 /// (i.e. all 1's). 00182 /// <p> 00183 /// Note : For example, if the bitmap is 00184 /// [0001 | 1100 | 0011 | 1111 | 0000 | 0000] and 00185 /// [00001111 | 00011111 | 11111111]. Refer to the paper for details. 00186 /// 00187 /// @param iBitmap the bitmap64 from which we create s-bitmap 00188 ///////////////////////////////////////////////////////////////////// 00189 void Bitmap64::CreateSBitmap(const Bitmap64 &iBitmap) 00190 { 00191 00192 #ifdef DEBUG_BITMAP64COUNT 00193 _countCreateSBitmap++; 00194 #endif 00195 00196 assert(_memory); 00197 assert(_memSizeInt == iBitmap._memSizeInt); 00198 00199 // we walk the memory in terms of shorts 00200 // msib: pointer to memory of ibitmap in terms of short 00201 // ms: pointer to memory as a pointer to shorts 00202 // ss: size of the memory in short 00203 unsigned short* ms = reinterpret_cast<unsigned short*>(_memory); 00204 const unsigned short* msib = 00205 reinterpret_cast<const unsigned short*> (iBitmap._memory); 00206 00207 // go thru each group of 4 shorts (note that 4 shorts is one customer) 00208 for (int i = 0; i < _memSizeShort; i += 4) 00209 { 00210 // _sBitmapLookupTable should take in a short and return a short 00211 // with the first 1 changed to a 00212 // 0 and all remaining bits set to 1 00213 if (msib[i + 1] > 0) 00214 { 00215 // Post-process the first short, set the others to all 1's 00216 ms[i] = USHRT_MAX; 00217 ms[i + 1] = _sBitmapLookupTable[msib[i + 1]]; 00218 ms[i + 2] = USHRT_MAX; 00219 ms[i + 3] = USHRT_MAX; 00220 } 00221 else if (msib[i] > 0) 00222 { 00223 ms[i] = _sBitmapLookupTable[msib[i]]; 00224 ms[i + 1] = 0; 00225 ms[i + 2] = USHRT_MAX; 00226 ms[i + 3] = USHRT_MAX; 00227 } 00228 else if (msib[i + 3] > 0) 00229 { 00230 ms[i] = 0; 00231 ms[i + 1] = 0; 00232 ms[i + 2] = USHRT_MAX; 00233 ms[i + 3] = _sBitmapLookupTable[msib[i + 3]]; 00234 } 00235 else 00236 { // Set first 3 shorts to 0, post-process the last short 00237 ms[i] = 0; 00238 ms[i + 1] = 0; 00239 ms[i + 2] = _sBitmapLookupTable[msib[i + 2]]; 00240 ms[i + 3] = 0; 00241 } 00242 } 00243 } 00244 00245 ///////////////////////////////////////////////////////////////////// 00246 /// create a c-bitmap for compression 00247 /// 00248 /// @param iBitmap the bitmap64 from which we create c-bitmap 00249 ///////////////////////////////////////////////////////////////////// 00250 void Bitmap64::CreateCBitmap(const Bitmap64 &iBitmap) 00251 { 00252 00253 #ifdef DEBUG_BITMAP64COUNT 00254 _countCreateCBitmap++; 00255 #endif 00256 00257 assert(_memory); 00258 assert(_memSizeInt == iBitmap._memSizeInt); 00259 00260 // we walk the memory in terms of shorts 00261 // msib: pointer to memory of ibitmap in terms of short 00262 // ms: pointer to memory as a pointer to shorts 00263 // ss: size of the memory in short 00264 unsigned short* ms = reinterpret_cast<unsigned short*>(_memory); 00265 const unsigned short* msib = 00266 reinterpret_cast<const unsigned short*> (iBitmap._memory); 00267 00268 // go thru each group of 4 shorts (note that 4 shorts is one customer) 00269 for (int i = 0; i < _memSizeShort; i += 4) 00270 { 00271 // _sBitmapLookupTable should take in a short and return a short 00272 // with the first 1 changed to a 00273 // 0 and all remaining bits set to 1 00274 if (msib[i + 1] > 0) 00275 { 00276 // Post-process the first short, set the others to all 1's 00277 ms[i] = USHRT_MAX; 00278 ms[i + 1] = _cBitmapLookupTable[msib[i + 1]]; 00279 ms[i + 2] = USHRT_MAX; 00280 ms[i + 3] = USHRT_MAX; 00281 } 00282 else if (msib[i] > 0) 00283 { 00284 ms[i] = _cBitmapLookupTable[msib[i]]; 00285 ms[i + 1] = 0; 00286 ms[i + 2] = USHRT_MAX; 00287 ms[i + 3] = USHRT_MAX; 00288 } 00289 else if (msib[i + 3] > 0) 00290 { 00291 ms[i] = 0; 00292 ms[i + 1] = 0; 00293 ms[i + 2] = USHRT_MAX; 00294 ms[i + 3] = _cBitmapLookupTable[msib[i + 3]]; 00295 } 00296 else 00297 { // Set first 3 shorts to 0, post-process the last short 00298 ms[i] = 0; 00299 ms[i + 1] = 0; 00300 ms[i + 2] = _cBitmapLookupTable[msib[i + 2]]; 00301 ms[i + 3] = 0; 00302 } 00303 } 00304 } 00305