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