/root/doris/be/src/gutil/bits.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2002 and onwards Google Inc. |
2 | | // |
3 | | // Derived from code by Moses Charikar |
4 | | |
5 | | #include "gutil/bits.h" |
6 | | |
7 | | #include <assert.h> |
8 | | |
9 | | // this array gives the number of bits for any number from 0 to 255 |
10 | | // (We could make these ints. The tradeoff is size (eg does it overwhelm |
11 | | // the cache?) vs efficiency in referencing sub-word-sized array elements) |
12 | | const char Bits::num_bits[] = { |
13 | | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, |
14 | | 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, |
15 | | 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, |
16 | | 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, |
17 | | 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, |
18 | | 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, |
19 | | 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, |
20 | | 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, |
21 | | 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; |
22 | | |
23 | 0 | int Bits::Count(const void* m, int num_bytes) { |
24 | 0 | int nbits = 0; |
25 | 0 | const uint8* s = (const uint8*)m; |
26 | 0 | for (int i = 0; i < num_bytes; i++) nbits += num_bits[*s++]; |
27 | 0 | return nbits; |
28 | 0 | } |
29 | | |
30 | 0 | int Bits::Difference(const void* m1, const void* m2, int num_bytes) { |
31 | 0 | int nbits = 0; |
32 | 0 | const uint8* s1 = (const uint8*)m1; |
33 | 0 | const uint8* s2 = (const uint8*)m2; |
34 | 0 | for (int i = 0; i < num_bytes; i++) nbits += num_bits[(*s1++) ^ (*s2++)]; |
35 | 0 | return nbits; |
36 | 0 | } |
37 | | |
38 | 0 | int Bits::CappedDifference(const void* m1, const void* m2, int num_bytes, int cap) { |
39 | 0 | int nbits = 0; |
40 | 0 | const uint8* s1 = (const uint8*)m1; |
41 | 0 | const uint8* s2 = (const uint8*)m2; |
42 | 0 | for (int i = 0; i < num_bytes && nbits <= cap; i++) nbits += num_bits[(*s1++) ^ (*s2++)]; |
43 | 0 | return nbits; |
44 | 0 | } |
45 | | |
46 | 0 | int Bits::Log2Floor_Portable(uint32 n) { |
47 | 0 | if (n == 0) return -1; |
48 | 0 | int log = 0; |
49 | 0 | uint32 value = n; |
50 | 0 | for (int i = 4; i >= 0; --i) { |
51 | 0 | int shift = (1 << i); |
52 | 0 | uint32 x = value >> shift; |
53 | 0 | if (x != 0) { |
54 | 0 | value = x; |
55 | 0 | log += shift; |
56 | 0 | } |
57 | 0 | } |
58 | 0 | assert(value == 1); |
59 | 0 | return log; |
60 | 0 | } |
61 | | |
62 | 0 | int Bits::Log2Ceiling(uint32 n) { |
63 | 0 | int floor = Log2Floor(n); |
64 | 0 | if (n == (n & ~(n - 1))) // zero or a power of two |
65 | 0 | return floor; |
66 | 0 | else |
67 | 0 | return floor + 1; |
68 | 0 | } |
69 | | |
70 | 0 | int Bits::Log2Ceiling64(uint64 n) { |
71 | 0 | int floor = Log2Floor64(n); |
72 | 0 | if (n == (n & ~(n - 1))) // zero or a power of two |
73 | 0 | return floor; |
74 | 0 | else |
75 | 0 | return floor + 1; |
76 | 0 | } |
77 | | |
78 | 0 | int Bits::FindLSBSetNonZero_Portable(uint32 n) { |
79 | 0 | int rc = 31; |
80 | 0 | for (int i = 4, shift = 1 << 4; i >= 0; --i) { |
81 | 0 | const uint32 x = n << shift; |
82 | 0 | if (x != 0) { |
83 | 0 | n = x; |
84 | 0 | rc -= shift; |
85 | 0 | } |
86 | 0 | shift >>= 1; |
87 | 0 | } |
88 | 0 | return rc; |
89 | 0 | } |