Coverage Report

Created: 2025-06-13 06:23

/src/brpc/src/butil/bit_array.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
// Date: Tue Feb 25 23:43:39 CST 2014
19
20
// Provide functions to get/set bits of an integral array. These functions
21
// are not threadsafe because operations on different bits may modify a same
22
// integer.
23
24
#ifndef BUTIL_BIT_ARRAY_H
25
#define BUTIL_BIT_ARRAY_H
26
27
#include <stdint.h>
28
29
namespace butil {
30
31
#define BIT_ARRAY_LEN(nbit) (((nbit) + 63 ) / 64 * 8)
32
33
// Create an array with at least |nbit| bits. The array is not cleared.
34
0
inline uint64_t* bit_array_malloc(size_t nbit) {
35
0
    if (!nbit) {
36
0
        return NULL;
37
0
    }
38
0
    return (uint64_t*)malloc(BIT_ARRAY_LEN(nbit)/*different from /8*/);
39
0
}
40
41
0
inline void bit_array_free(uint64_t* array) {
42
0
    free(array);
43
0
}
44
45
// Set bit 0 ~ nbit-1 of |array| to be 0
46
0
inline void bit_array_clear(uint64_t* array, size_t nbit) {
47
0
    const size_t off = (nbit >> 6);
48
0
    memset(array, 0, off * 8);
49
0
    const size_t last = (off << 6);
50
0
    if (last != nbit) {
51
0
        array[off] &= ~((((uint64_t)1) << (nbit - last)) - 1);
52
0
    }
53
0
}
54
55
// Set i-th bit (from left, counting from 0) of |array| to be 1
56
0
inline void bit_array_set(uint64_t* array, size_t i) {
57
0
    const size_t off = (i >> 6);
58
0
    array[off] |= (((uint64_t)1) << (i - (off << 6)));
59
0
}
60
61
// Set i-th bit (from left, counting from 0) of |array| to be 0
62
0
inline void bit_array_unset(uint64_t* array, size_t i) {
63
0
    const size_t off = (i >> 6);
64
0
    array[off] &= ~(((uint64_t)1) << (i - (off << 6)));
65
0
}
66
67
// Get i-th bit (from left, counting from 0) of |array|
68
0
inline uint64_t bit_array_get(const uint64_t* array, size_t i) {
69
0
    const size_t off = (i >> 6);
70
0
    return (array[off] & (((uint64_t)1) << (i - (off << 6))));
71
0
}
72
73
// Find index of first 1-bit from bit |begin| to |end| in |array|.
74
// Returns |end| if all bits are 0.
75
// This function is of O(nbit) complexity.
76
0
inline size_t bit_array_first1(const uint64_t* array, size_t begin, size_t end) {
77
0
    size_t off1 = (begin >> 6);
78
0
    const size_t first = (off1 << 6);
79
0
    if (first != begin) {
80
0
        const uint64_t v =
81
0
            array[off1] & ~((((uint64_t)1) << (begin - first)) - 1);
82
0
        if (v) {
83
0
            return std::min(first + __builtin_ctzl(v), end);
84
0
        }
85
0
        ++off1;
86
0
    }
87
0
    
88
0
    const size_t off2 = (end >> 6);
89
0
    for (size_t i = off1; i < off2; ++i) {
90
0
        if (array[i]) {
91
0
            return i * 64 + __builtin_ctzl(array[i]);
92
0
        }
93
0
    }
94
0
    const size_t last = (off2 << 6);
95
0
    if (last != end && array[off2]) {
96
0
        return std::min(last + __builtin_ctzl(array[off2]), end);
97
0
    }
98
0
    return end;
99
0
}
100
101
}  // end namespace butil
102
103
#endif  // BUTIL_BIT_ARRAY_H