LCOV - code coverage report
Current view: top level - src - BitPage.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 28 28 100.0 %
Date: 2020-12-16 07:07:30 Functions: 5 5 100.0 %
Branches: 8 10 80.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef BIT_PAGE_HPP
       2                 :            : #define BIT_PAGE_HPP
       3                 :            : 
       4                 :            : #include <assert.h>
       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,
     120                 :            :                  EntityHandle start ) const;
     121                 :            : 
     122                 :            :   private:
     123                 :            :     /**\brief The actual array of bytes */
     124                 :            :     char byteArray[BitTag::PageSize];
     125                 :            : };
     126                 :            : 
     127                 :    2616384 : 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                 :    2616384 :     unsigned char mask = (unsigned char)( 1 << per_ent ) - 1;  // 2^per_ent - 1
     132                 :    2616384 :     int byte           = ( offset * per_ent ) >> 3;            // shifting 3 is dividing by eight
     133                 :    2616384 :     int bit            = ( offset * per_ent ) & 7;             // masking with 7 is modulo eight
     134         [ -  + ]:    2616384 :     assert( byte < BitTag::PageSize );
     135                 :    2616384 :     return (unsigned char)( byteArray[byte] >> bit ) & mask;
     136                 :            : }
     137                 :            : 
     138                 :    4335350 : inline void BitPage::set_bits( int offset, int per_ent, unsigned char bits )
     139                 :            : {
     140                 :    4335350 :     int byte = ( offset * per_ent ) >> 3;  // shifting 3 is dividing by eight
     141                 :    4335350 :     int bit  = ( offset * per_ent ) & 7;   // masking with 7 is modulo eight
     142         [ -  + ]:    4335350 :     assert( byte < BitTag::PageSize );
     143                 :            :     // Assume per_ent is a power of two, which should be guaranteed
     144                 :            :     // by higher-level code.
     145                 :    4335350 :     unsigned char mask = (unsigned char)( ( 1 << per_ent ) - 1 ) << bit;
     146                 :    4335350 :     byteArray[byte]    = (char)( ( byteArray[byte] & ~mask ) | ( ( bits << bit ) & mask ) );
     147                 :    4335350 : }
     148                 :            : 
     149                 :          9 : inline void BitPage::get_bits( int offset, int count, int per_ent, unsigned char* data ) const
     150                 :            : {
     151                 :          9 :     unsigned char* end = data + count;
     152         [ +  + ]:      60161 :     while( data != end )
     153                 :      60152 :         *( data++ ) = get_bits( offset++, per_ent );
     154                 :          9 : }
     155                 :            : 
     156                 :        308 : inline void BitPage::set_bits( int offset, int count, int per_ent, const unsigned char* data )
     157                 :            : {
     158                 :        308 :     const unsigned char* end = data + count;
     159         [ +  + ]:      65640 :     while( data != end )
     160                 :      65332 :         set_bits( offset++, per_ent, *( data++ ) );
     161                 :        308 : }
     162                 :            : 
     163                 :       1151 : inline void BitPage::set_bits( int offset, int count, int per_ent, unsigned char value )
     164                 :            : {
     165                 :       1151 :     int end = offset + count;
     166         [ +  + ]:       2930 :     while( offset < end )
     167                 :       1779 :         set_bits( offset++, per_ent, value );
     168                 :       1151 : }
     169                 :            : 
     170                 :            : }  // namespace moab
     171                 :            : 
     172                 :            : #endif

Generated by: LCOV version 1.11