Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef BIT_PAGE_HPP 00002 #define BIT_PAGE_HPP 00003 00004 #include <cassert> 00005 #include "BitTag.hpp" 00006 00007 namespace moab 00008 { 00009 00010 class Range; 00011 00012 /**\brief bit tag data 00013 * 00014 * This class represents a fixed-size block of memory in which bit tag 00015 * values are stored. 00016 */ 00017 class BitPage 00018 { 00019 public: 00020 /**\brief Initialize memory 00021 * 00022 *\param bits_per_ent Number of bits in each tag value. 00023 * MUST BE A POWER OF TWO. 00024 *\param init_val The lower bits_per_ent bits of this byte are 00025 * used to initialize each tag value. 00026 */ 00027 BitPage( int bits_per_ent, unsigned char init_val ); 00028 00029 /**\brief Get tag values 00030 * 00031 * Get 'count' tag values, beginning with the one at 'offset'. 00032 *\param offset Offset into list of values, where a value of zero indicates 00033 * the first tag value, a value of one indicates the second 00034 * tag value, etc. NOTE: This is the value offset, not the 00035 * bit offset. 00036 *\param count Number of consecutive tag values to get. 00037 *\param bits_per_ent Number of bits composing each tag value. 00038 * NOTE: Must be a power of two. 00039 *\param data Memory into which to copy tag values. Each value is copied 00040 * into a separate byte, such that the lower bits of the bit 00041 * contain the tag value and any unused higher bits are zero. 00042 */ 00043 void get_bits( int offset, int count, int bits_per_ent, unsigned char* data ) const; 00044 00045 /**\brief Set tag values 00046 * 00047 * Set 'count' tag values, beginning with the one at 'offset'. 00048 *\param offset Offset into list of values, where a value of zero indicates 00049 * the first tag value, a value of one indicates the second 00050 * tag value, etc. NOTE: This is the value offset, not the 00051 * bit offset. 00052 *\param count Number of consecutive tag values to set. 00053 *\param bits_per_ent Number of bits composing each tag value. 00054 * NOTE: Must be a power of two. 00055 *\param data Memory from which to copy tag values. Each value is copied 00056 * from a separate byte. The lower 'bits_per_ent' of each 00057 * byte are used as the tag value. Any additional higher bits 00058 * are ignored. 00059 */ 00060 void set_bits( int offset, int count, int bits_per_ent, const unsigned char* data ); 00061 00062 /**\brief Set several tag values to the same value. 00063 * 00064 * Set 'count' tag values to specified value. 00065 *\param offset Offset into list of values, where a value of zero indicates 00066 * the first tag value, a value of one indicates the second 00067 * tag value, etc. NOTE: This is the value offset, not the 00068 * bit offset. 00069 *\param count Number of consecutive tag values to set. 00070 *\param bits_per_ent Number of bits composing each tag value. 00071 * NOTE: Must be a power of two. 00072 *\param value The lower 'bits_per_ent' of this 00073 * byte are used as the tag value. Any additional higher bits 00074 * are ignored. 00075 */ 00076 void set_bits( int offset, int count, int bits_per_ent, unsigned char value ); 00077 00078 /**\brief Get tag value 00079 * 00080 * Get one tag value. 00081 *\param offset Offset into list of values, where a value of zero indicates 00082 * the first tag value, a value of one indicates the second 00083 * tag value, etc. NOTE: This is the value offset, not the 00084 * bit offset. 00085 *\param bits_per_ent Number of bits composing each tag value. 00086 * NOTE: Must be a power of two. 00087 *\return A byte containing the tag value in the lower bits with 00088 * any unused higher bits zeroed. 00089 */ 00090 unsigned char get_bits( int offset, int bits_per_ent ) const; 00091 00092 /**\brief Set tag value 00093 * 00094 * Set tag value. 00095 *\param offset Offset into list of values, where a value of zero indicates 00096 * the first tag value, a value of one indicates the second 00097 * tag value, etc. NOTE: This is the value offset, not the 00098 * bit offset. 00099 *\param bits_per_ent Number of bits composing each tag value. 00100 * NOTE: Must be a power of two. 00101 *\param value The lower 'bits_per_ent' of this 00102 * byte are used as the tag value. Any additional higher bits 00103 * are ignored. 00104 */ 00105 void set_bits( int offset, int bits_per_ent, unsigned char data ); 00106 00107 /**\brief Search stored values for specified value. 00108 * 00109 * Find the offsets n in the data at which the specified value occurs, 00110 * and for each one insert 'start + n' into the passed Range. 00111 *\param value The value to look for 00112 *\param offset The offset at which to begin searching 00113 *\param count The number of values to search 00114 *\param bits_per_ent Number of bits composing each tag value. 00115 *\param results Result list. 00116 *\param start The handle of the entity corresponding to the 00117 * tag value stored at 'offset' 00118 */ 00119 void search( unsigned char value, int offset, int count, int bits_per_ent, Range& results, EntityHandle start ) 00120 const; 00121 00122 private: 00123 /**\brief The actual array of bytes */ 00124 char byteArray[BitTag::PageSize]; 00125 }; 00126 00127 inline unsigned char BitPage::get_bits( int offset, int per_ent ) const 00128 { 00129 // Assume per_ent is a power of two, which should be guaranteed 00130 // by higher-level code. 00131 unsigned char mask = (unsigned char)( 1 << per_ent ) - 1; // 2^per_ent - 1 00132 int byte = ( offset * per_ent ) >> 3; // shifting 3 is dividing by eight 00133 int bit = ( offset * per_ent ) & 7; // masking with 7 is modulo eight 00134 assert( byte < BitTag::PageSize ); 00135 return (unsigned char)( byteArray[byte] >> bit ) & mask; 00136 } 00137 00138 inline void BitPage::set_bits( int offset, int per_ent, unsigned char bits ) 00139 { 00140 int byte = ( offset * per_ent ) >> 3; // shifting 3 is dividing by eight 00141 int bit = ( offset * per_ent ) & 7; // masking with 7 is modulo eight 00142 assert( byte < BitTag::PageSize ); 00143 // Assume per_ent is a power of two, which should be guaranteed 00144 // by higher-level code. 00145 unsigned char mask = (unsigned char)( ( 1 << per_ent ) - 1 ) << bit; 00146 byteArray[byte] = (char)( ( byteArray[byte] & ~mask ) | ( ( bits << bit ) & mask ) ); 00147 } 00148 00149 inline void BitPage::get_bits( int offset, int count, int per_ent, unsigned char* data ) const 00150 { 00151 unsigned char* end = data + count; 00152 while( data != end ) 00153 *( data++ ) = get_bits( offset++, per_ent ); 00154 } 00155 00156 inline void BitPage::set_bits( int offset, int count, int per_ent, const unsigned char* data ) 00157 { 00158 const unsigned char* end = data + count; 00159 while( data != end ) 00160 set_bits( offset++, per_ent, *( data++ ) ); 00161 } 00162 00163 inline void BitPage::set_bits( int offset, int count, int per_ent, unsigned char value ) 00164 { 00165 int end = offset + count; 00166 while( offset < end ) 00167 set_bits( offset++, per_ent, value ); 00168 } 00169 00170 } // namespace moab 00171 00172 #endif