Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
BitPage.hpp
Go to the documentation of this file.
1 #ifndef BIT_PAGE_HPP
2 #define BIT_PAGE_HPP
3 
4 #include <cassert>
5 #include "BitTag.hpp"
6 
7 namespace moab
8 {
9 
10 class Range;
11 
12 /**\brief bit tag data
13  *
14  * This class represents a fixed-size block of memory in which bit tag
15  * values are stored.
16  */
17 class BitPage
18 {
19  public:
20  /**\brief Initialize memory
21  *
22  *\param bits_per_ent Number of bits in each tag value.
23  * MUST BE A POWER OF TWO.
24  *\param init_val The lower bits_per_ent bits of this byte are
25  * used to initialize each tag value.
26  */
27  BitPage( int bits_per_ent, unsigned char init_val );
28 
29  /**\brief Get tag values
30  *
31  * Get 'count' tag values, beginning with the one at 'offset'.
32  *\param offset Offset into list of values, where a value of zero indicates
33  * the first tag value, a value of one indicates the second
34  * tag value, etc. NOTE: This is the value offset, not the
35  * bit offset.
36  *\param count Number of consecutive tag values to get.
37  *\param bits_per_ent Number of bits composing each tag value.
38  * NOTE: Must be a power of two.
39  *\param data Memory into which to copy tag values. Each value is copied
40  * into a separate byte, such that the lower bits of the bit
41  * contain the tag value and any unused higher bits are zero.
42  */
43  void get_bits( int offset, int count, int bits_per_ent, unsigned char* data ) const;
44 
45  /**\brief Set tag values
46  *
47  * Set 'count' tag values, beginning with the one at 'offset'.
48  *\param offset Offset into list of values, where a value of zero indicates
49  * the first tag value, a value of one indicates the second
50  * tag value, etc. NOTE: This is the value offset, not the
51  * bit offset.
52  *\param count Number of consecutive tag values to set.
53  *\param bits_per_ent Number of bits composing each tag value.
54  * NOTE: Must be a power of two.
55  *\param data Memory from which to copy tag values. Each value is copied
56  * from a separate byte. The lower 'bits_per_ent' of each
57  * byte are used as the tag value. Any additional higher bits
58  * are ignored.
59  */
60  void set_bits( int offset, int count, int bits_per_ent, const unsigned char* data );
61 
62  /**\brief Set several tag values to the same value.
63  *
64  * Set 'count' tag values to specified value.
65  *\param offset Offset into list of values, where a value of zero indicates
66  * the first tag value, a value of one indicates the second
67  * tag value, etc. NOTE: This is the value offset, not the
68  * bit offset.
69  *\param count Number of consecutive tag values to set.
70  *\param bits_per_ent Number of bits composing each tag value.
71  * NOTE: Must be a power of two.
72  *\param value The lower 'bits_per_ent' of this
73  * byte are used as the tag value. Any additional higher bits
74  * are ignored.
75  */
76  void set_bits( int offset, int count, int bits_per_ent, unsigned char value );
77 
78  /**\brief Get tag value
79  *
80  * Get one tag value.
81  *\param offset Offset into list of values, where a value of zero indicates
82  * the first tag value, a value of one indicates the second
83  * tag value, etc. NOTE: This is the value offset, not the
84  * bit offset.
85  *\param bits_per_ent Number of bits composing each tag value.
86  * NOTE: Must be a power of two.
87  *\return A byte containing the tag value in the lower bits with
88  * any unused higher bits zeroed.
89  */
90  unsigned char get_bits( int offset, int bits_per_ent ) const;
91 
92  /**\brief Set tag value
93  *
94  * Set tag value.
95  *\param offset Offset into list of values, where a value of zero indicates
96  * the first tag value, a value of one indicates the second
97  * tag value, etc. NOTE: This is the value offset, not the
98  * bit offset.
99  *\param bits_per_ent Number of bits composing each tag value.
100  * NOTE: Must be a power of two.
101  *\param value The lower 'bits_per_ent' of this
102  * byte are used as the tag value. Any additional higher bits
103  * are ignored.
104  */
105  void set_bits( int offset, int bits_per_ent, unsigned char data );
106 
107  /**\brief Search stored values for specified value.
108  *
109  * Find the offsets n in the data at which the specified value occurs,
110  * and for each one insert 'start + n' into the passed Range.
111  *\param value The value to look for
112  *\param offset The offset at which to begin searching
113  *\param count The number of values to search
114  *\param bits_per_ent Number of bits composing each tag value.
115  *\param results Result list.
116  *\param start The handle of the entity corresponding to the
117  * tag value stored at 'offset'
118  */
119  void search( unsigned char value, int offset, int count, int bits_per_ent, Range& results, EntityHandle start )
120  const;
121 
122  private:
123  /**\brief The actual array of bytes */
125 };
126 
127 inline unsigned char BitPage::get_bits( int offset, int per_ent ) const
128 {
129  // Assume per_ent is a power of two, which should be guaranteed
130  // by higher-level code.
131  unsigned char mask = (unsigned char)( 1 << per_ent ) - 1; // 2^per_ent - 1
132  int byte = ( offset * per_ent ) >> 3; // shifting 3 is dividing by eight
133  int bit = ( offset * per_ent ) & 7; // masking with 7 is modulo eight
134  assert( byte < BitTag::PageSize );
135  return (unsigned char)( byteArray[byte] >> bit ) & mask;
136 }
137 
138 inline void BitPage::set_bits( int offset, int per_ent, unsigned char bits )
139 {
140  int byte = ( offset * per_ent ) >> 3; // shifting 3 is dividing by eight
141  int bit = ( offset * per_ent ) & 7; // masking with 7 is modulo eight
142  assert( byte < BitTag::PageSize );
143  // Assume per_ent is a power of two, which should be guaranteed
144  // by higher-level code.
145  unsigned char mask = (unsigned char)( ( 1 << per_ent ) - 1 ) << bit;
146  byteArray[byte] = (char)( ( byteArray[byte] & ~mask ) | ( ( bits << bit ) & mask ) );
147 }
148 
149 inline void BitPage::get_bits( int offset, int count, int per_ent, unsigned char* data ) const
150 {
151  unsigned char* end = data + count;
152  while( data != end )
153  *( data++ ) = get_bits( offset++, per_ent );
154 }
155 
156 inline void BitPage::set_bits( int offset, int count, int per_ent, const unsigned char* data )
157 {
158  const unsigned char* end = data + count;
159  while( data != end )
160  set_bits( offset++, per_ent, *( data++ ) );
161 }
162 
163 inline void BitPage::set_bits( int offset, int count, int per_ent, unsigned char value )
164 {
165  int end = offset + count;
166  while( offset < end )
167  set_bits( offset++, per_ent, value );
168 }
169 
170 } // namespace moab
171 
172 #endif