github.com/matrixorigin/matrixone@v1.2.0/cgo/bitmap.h (about)

     1  /* 
     2   * Copyright 2021 Matrix Origin
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  #ifndef _BITMAP_H_
    18  #define _BITMAP_H_
    19  
    20  #include "mo.h"
    21  #include <string.h>
    22  
    23  /*
    24   * Null bitmap operations.    Bitmap is an array of unit64_t and nbits of bits, nbits > 0.
    25   * Each of the nbits is a bit from position pos 0 to pos nbits - 1
    26   *
    27   * MUST MATCH GO IMPLEMENTATION.
    28   */
    29  
    30  /* bitmap in number of bytes. */
    31  static inline uint64_t bitmap_nbyte(uint64_t nbits) {
    32      return (nbits + 7) >> 3; 
    33  }
    34  /* return number of uint64 that can holds nbits */
    35  static inline uint64_t bitmap_size(uint64_t nbits) {
    36      return (nbits + 63) >> 6;
    37  }
    38  /* return index into array of the bit position */
    39  static inline uint64_t bitmap_pos2idx(uint64_t pos) {
    40      return pos >> 6;
    41  }
    42  /* return mask of the bit position */
    43  static inline uint64_t bitmap_pos2mask(uint64_t pos) {
    44      uint64_t mask = 1;
    45      return mask << (pos & 63);
    46  }
    47  
    48  static inline bool bitmap_test(uint64_t *p, uint64_t pos) {
    49      return (p[bitmap_pos2idx(pos)] & bitmap_pos2mask(pos)) != 0;
    50  }
    51  
    52  static inline void bitmap_set(uint64_t *p, uint64_t pos) {
    53      p[bitmap_pos2idx(pos)] |= bitmap_pos2mask(pos);
    54  }
    55  
    56  static inline void bitmap_clear(uint64_t *p, uint64_t pos) {
    57      p[bitmap_pos2idx(pos)] &= ~bitmap_pos2mask(pos);
    58  }
    59  
    60  static inline void bitmap_zeros(uint64_t *p, uint64_t nbits) {
    61      memset(p, 0, bitmap_nbyte(nbits));
    62  }
    63  
    64  static inline void bitmap_ones(uint64_t *p, uint64_t nbits) {
    65      memset(p, 0xFF, bitmap_nbyte(nbits));
    66  }
    67  
    68  static inline void bitmap_copy(uint64_t *dst, uint64_t *src, uint64_t nbits) {
    69      memcpy(dst, src, bitmap_nbyte(nbits));
    70  }
    71  
    72  static inline void bitmap_and(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) {
    73      uint64_t sz = bitmap_size(nbits);
    74      for (uint64_t i = 0; i < sz; ++i) {
    75          dst[i] = a[i] & b[i];
    76      }
    77  }
    78  static inline void bitmap_or(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) {
    79      uint64_t sz = bitmap_size(nbits);
    80      for (uint64_t i = 0; i < sz; ++i) {
    81          dst[i] = a[i] | b[i];
    82      }
    83  }
    84  
    85  static inline void bitmap_not(uint64_t *dst, uint64_t *a, uint64_t nbits) {
    86      uint64_t sz = bitmap_size(nbits);
    87      for (uint64_t i = 0; i < sz; ++i) {
    88          dst[i] = ~a[i]; 
    89      }
    90  }
    91  
    92  static inline uint64_t bitmap_lastmask(uint64_t nbits) {
    93      uint64_t mask = bitmap_pos2mask(nbits - 1);
    94      /* 
    95       * For nbits = 0, 64, ...   mask will be 1 << 63. 
    96       * the following overflowed expression is the correct answer.
    97       */ 
    98      return (mask << 1) - 1;
    99  }
   100  
   101  static inline uint64_t bitmap_count(uint64_t *p, uint64_t nbits) {
   102      if (nbits == 0) {
   103          return 0;
   104      } else {
   105          uint64_t sz = bitmap_size(nbits);
   106          uint64_t mask = bitmap_lastmask(nbits);
   107          uint64_t cnt = __builtin_popcountll(p[sz - 1] & mask);
   108          for (uint64_t i = 0; (i + 1) < sz; ++i) {
   109              cnt += __builtin_popcountll(p[i]);
   110          }
   111          return cnt;
   112      }
   113  }
   114  
   115  static inline bool bitmap_empty(uint64_t *p, uint64_t nbits) {
   116      if (nbits == 0) {
   117          return true;
   118      } else {
   119          uint64_t sz = bitmap_size(nbits);
   120          uint64_t mask = bitmap_lastmask(nbits);
   121          if ((p[sz-1] & mask) != 0) {
   122              return false;
   123          }
   124          for (uint64_t i = 0; (i + 1) < sz; ++i) {
   125              if (p[i] != 0) {
   126                  return false;
   127              }
   128          }
   129          return true;
   130      }
   131  }
   132  
   133  #endif /* _BITMAP_H_ */