![]() |
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
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