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 "SPACE.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 00127 bool operator<(const BitSet& rhs) const; 00128 00130 ~BitSet(); 00131 00132 // somewhat slow random access. Fast iterating done 00133 // with BitSetIterator 00134 bool operator[](int i) const; 00135 00136 /* 00137 logic operations 00138 */ 00139 00141 void setTrue(int i); // set bit to 1 00142 00144 void setFalse(int i); // set bit to 0 00145 00147 00150 bool isEmpty() const; 00151 00153 00156 bool isFull() const; 00157 00159 int size() const; 00160 static int initialize(); 00161 00162 int linearSize() const; 00163 00164 void linearIn(const void* const inBuf); 00165 00166 void linearOut(void* const a_outBuf) const; 00167 00168 // not for public, used by memory tracker. 00169 static long int bytes; 00170 static long int peak; 00171 00172 private: 00173 friend class BitSetIterator; 00174 00175 BITSETWORD* m_bits; 00176 int m_size; 00177 int m_length; //length of char array, not bit length 00178 00179 static BITSETWORD trueMasks[BITSETWORDSIZE]; //10000000, 01000000, 00100000, .... 00180 }; 00181 00182 // somewhat slow random access. Fast iterating done 00183 // with BitSetIterator 00184 inline bool BitSet::operator[](int i) const 00185 { 00186 CH_assert(i>=0); 00187 CH_assert(i<m_size); 00188 int index = i/BITSETWORDSIZE; 00189 CH_assert(index < m_length); 00190 int remainder = i-BITSETWORDSIZE*index; 00191 BITSETWORD tmp = m_bits[index] & trueMasks[remainder]; 00192 return tmp > 0; 00193 } 00194 00195 inline int BitSet::size() const 00196 { 00197 return m_size; 00198 } 00199 00201 /* Iterate over bits in a BitSet. return true if bit is 1 00202 00203 example: 35 bits in bitset, BITSETWORDSIZE=8: 00204 00205 currently at the 22nd bit: (bit # =21) 00206 00207 |-m_index = 2---| 00208 +-------+-------+-------+-------+-------+ 00209 1111111110001111111100011111111100011111 00210 ^ ^ 00211 m_remainder |----| = 6 ^ ^ 00212 |--| m_partialBits = 3 00213 00214 returns: false for operator() 00215 . 00216 */ 00217 class BitSetIterator 00218 { 00219 public: 00221 BitSetIterator(); 00222 00224 BitSetIterator(const BitSet& bitset); 00225 00226 // copy and assign should be fine 00227 00229 bool operator()() const; 00230 00232 bool ok() const; 00233 00235 void operator++(); 00236 00238 void begin(); 00239 00241 void end(); 00242 00243 private: 00244 int m_index; 00245 int m_remainder; 00246 int m_length; 00247 00248 int m_partialBits; 00249 const BitSet* m_bitset; 00250 static BitSet emptyBitSet; 00251 }; 00252 00253 inline 00254 BitSetIterator::BitSetIterator() 00255 : 00256 m_index(0), 00257 m_remainder(0), 00258 m_length(0), 00259 m_partialBits(0), 00260 m_bitset(&emptyBitSet) 00261 {} 00262 00263 inline 00264 BitSetIterator::BitSetIterator(const BitSet& a_bitset) 00265 :m_index(0), m_remainder(0), m_length(a_bitset.m_length - 1), 00266 m_partialBits(a_bitset.m_size - BITSETWORDSIZE*(a_bitset.m_length - 1)), 00267 m_bitset(&a_bitset) 00268 { 00269 if(m_partialBits == BITSETWORDSIZE) 00270 { 00271 m_partialBits = 0; 00272 m_length++; 00273 } 00274 } 00275 00276 inline 00277 bool BitSetIterator::operator()() const 00278 { 00279 return (m_bitset->m_bits[m_index] & BitSet::trueMasks[m_remainder] ) > 0; 00280 } 00281 00282 inline 00283 bool BitSetIterator::ok() const 00284 { 00285 if(m_index < m_length) return true; 00286 if(m_remainder < m_partialBits) return true; 00287 return false; 00288 } 00289 00290 inline 00291 void BitSetIterator::operator++() 00292 { 00293 ++m_remainder; 00294 if(m_remainder == BITSETWORDSIZE) 00295 { 00296 m_remainder = 0; 00297 ++m_index; 00298 } 00299 } 00300 00301 #endif