00001 /* _______ __ 00002 / ___/ / ___ __ _ / / ___ 00003 / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00004 \___/_//_/\___/_/_/_/_.__/\___/ 00005 */ 00006 // CHOMBO Copyright (c) 2000-2004, The Regents of the University of 00007 // California, through Lawrence Berkeley National Laboratory (subject to 00008 // receipt of any required approvals from U.S. Dept. of Energy). All 00009 // rights reserved. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are met: 00013 // 00014 // (1) Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // (2) Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // (3) Neither the name of Lawrence Berkeley National Laboratory, U.S. 00020 // Dept. of Energy nor the names of its contributors may be used to endorse 00021 // or promote products derived from this software without specific prior 00022 // written permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00026 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00027 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00028 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00029 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00030 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00031 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00032 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00033 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00034 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 // 00036 // You are under no obligation whatsoever to provide any bug fixes, 00037 // patches, or upgrades to the features, functionality or performance of 00038 // the source code ("Enhancements") to anyone; however, if you choose to 00039 // make your Enhancements available either publicly, or directly to 00040 // Lawrence Berkeley National Laboratory, without imposing a separate 00041 // written license agreement for such Enhancements, then you hereby grant 00042 // the following license: a non-exclusive, royalty-free perpetual license 00043 // to install, use, modify, prepare derivative works, incorporate into 00044 // other computer software, distribute, and sublicense such Enhancements or 00045 // derivative works thereof, in binary and source code form. 00046 // 00047 // TRADEMARKS. Product and company names mentioned herein may be the 00048 // trademarks of their respective owners. Any rights not expressly granted 00049 // herein are reserved. 00050 // 00051 00052 #ifndef _BITSET_H_ 00053 #define _BITSET_H_ 00054 00055 // 00056 // Arch dependant setting for what a BITSETWORD should be 00057 // BITSETWORD is the smallest efficiently accessible memory 00058 // object. BITSETWORD_BITS is the size, in bits, of this object 00059 // 00060 // Later I can make this object use a Pool, and we can 00061 // avoid all the memory system call overhead for creation and 00062 // use placement new. 00063 // 00064 00065 #define BITSETWORD unsigned int 00066 const int BITSETWORDSIZE = 8*sizeof(unsigned int); 00067 00068 // BITSETWORDSIZE is no the same as sizeof(BITSETWORD). This is the number of bits, not chars 00069 #include <assert.h> 00070 #include <iostream> 00071 00072 using std::ostream; 00073 00074 class BitSetIterator; 00075 00077 /* stores a contiguous memory chunk and represents true with a 1 bit 00078 and false with a 0 bit. 00079 00080 example: 35 bits, set to true, BITSETWORDSIZE=8: 00081 00082 m_index = 5 (need at least 5 BITSETWORDS to hold that many bits) 00083 m_size = 35 00084 00085 +-------+-------+-------+-------+-------+ 00086 1111111111111111111111111111111111111111 00087 00088 now, set bit 35 to 0 00089 00090 index = 35/BITSETWORDSIZE = 4 , hence, we are in the fourth BITSETWORD. 00091 mask = 35 - 4*BITSETWORDSIZE = 3 hence, we are in the third bit of the fourth word 00092 00093 now, we can use the masks: 00094 static BITSETWORD trueMasks[BITSETWORDSIZE]; //10000000, 01000000, 00100000, .... 00095 00096 word[index] = word[index] & ~trueMasks[mask] (~trueMasks[3] = 11101111) 00097 00098 now we have: 00099 00100 +-------+-------+-------+-------+-------+ 00101 1111111111111111111111111111111111101111 00102 */ 00103 class BitSet 00104 { 00105 public: 00107 BitSet(); 00108 00110 BitSet(int bits, bool init); 00111 00113 void define(int bits, bool init); 00114 00116 BitSet(const BitSet& rhs); 00117 00119 BitSet& operator=(const BitSet& rhs); 00120 00122 ~BitSet(); 00123 00124 // somewhat slow random access. Fast iterating done 00125 // with BitSetIterator 00126 bool operator[](int i) const; 00127 00128 /* 00129 logic operations 00130 */ 00131 00133 void setTrue(int i); // set bit to 1 00134 00136 void setFalse(int i); // set bit to 0 00137 00139 00142 bool isEmpty() const; 00143 00145 00148 bool isFull() const; 00149 00151 int size() const; 00152 static int initialize(); 00153 00154 int linearSize() const; 00155 00156 void linearIn(const void* const inBuf); 00157 00158 void linearOut(void* const a_outBuf) const; 00159 00160 // not for public, used by memory tracker. 00161 static long int bytes; 00162 static long int peak; 00163 00164 private: 00165 friend class BitSetIterator; 00166 00167 BITSETWORD* m_bits; 00168 int m_size; 00169 int m_length; //length of char array, not bit length 00170 00171 static BITSETWORD trueMasks[BITSETWORDSIZE]; //10000000, 01000000, 00100000, .... 00172 }; 00173 00174 // somewhat slow random access. Fast iterating done 00175 // with BitSetIterator 00176 inline bool BitSet::operator[](int i) const 00177 { 00178 assert(i>=0); 00179 assert(i<m_size); 00180 int index = i/BITSETWORDSIZE; 00181 assert(index < m_length); 00182 int remainder = i-BITSETWORDSIZE*index; 00183 BITSETWORD tmp = m_bits[index] & trueMasks[remainder]; 00184 return tmp > 0; 00185 } 00186 00187 inline int BitSet::size() const 00188 { 00189 return m_size; 00190 } 00191 00193 /* Iterate over bits in a BitSet. return true if bit is 1 00194 00195 example: 35 bits in bitset, BITSETWORDSIZE=8: 00196 00197 currently at the 22nd bit: (bit # =21) 00198 00199 |-m_index = 2---| 00200 +-------+-------+-------+-------+-------+ 00201 1111111110001111111100011111111100011111 00202 ^ ^ 00203 m_remainder |----| = 6 ^ ^ 00204 |--| m_partialBits = 3 00205 00206 returns: false for operator() 00207 . 00208 */ 00209 class BitSetIterator 00210 { 00211 public: 00213 BitSetIterator(); 00214 00216 BitSetIterator(const BitSet& bitset); 00217 00218 // copy and assign should be fine 00219 00221 bool operator()() const; 00222 00224 bool ok() const; 00225 00227 void operator++(); 00228 00230 void begin(); 00231 00233 void end(); 00234 00235 private: 00236 int m_index; 00237 int m_remainder; 00238 int m_length; 00239 00240 int m_partialBits; 00241 const BitSet* m_bitset; 00242 static BitSet emptyBitSet; 00243 }; 00244 00245 inline 00246 BitSetIterator::BitSetIterator() 00247 : 00248 m_index(0), 00249 m_remainder(0), 00250 m_length(0), 00251 m_partialBits(0), 00252 m_bitset(&emptyBitSet) 00253 {} 00254 00255 inline 00256 BitSetIterator::BitSetIterator(const BitSet& a_bitset) 00257 :m_index(0), m_remainder(0), m_length(a_bitset.m_length - 1), 00258 m_partialBits(a_bitset.m_size - BITSETWORDSIZE*(a_bitset.m_length - 1)), 00259 m_bitset(&a_bitset) 00260 { 00261 if(m_partialBits == BITSETWORDSIZE) 00262 { 00263 m_partialBits = 0; 00264 m_length++; 00265 } 00266 } 00267 00268 inline 00269 bool BitSetIterator::operator()() const 00270 { 00271 return (m_bitset->m_bits[m_index] & BitSet::trueMasks[m_remainder] ) > 0; 00272 } 00273 00274 inline 00275 bool BitSetIterator::ok() const 00276 { 00277 if(m_index < m_length) return true; 00278 if(m_remainder < m_partialBits) return true; 00279 return false; 00280 } 00281 00282 inline 00283 void BitSetIterator::operator++() 00284 { 00285 ++m_remainder; 00286 if(m_remainder == BITSETWORDSIZE) 00287 { 00288 m_remainder = 0; 00289 ++m_index; 00290 } 00291 } 00292 00293 #endif