Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
BitPage.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines