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_ */