github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/subnet/bitfield256.go (about) 1 package subnet 2 3 import ( 4 "fmt" 5 "math/bits" 6 ) 7 8 // Bitfield256 represents 0 - 255 unique bytes. 9 type Bitfield256 [4]uint64 10 11 // SetBit sets the 1<<bv bit of the bitfield to 1. 12 func (b *Bitfield256) SetBit(bv byte) { 13 b[bv>>6] |= uint64(1) << uint64(bv&0x3f) 14 } 15 16 // ClearBit clears the 1<<bv bit of the bitfield to 0. 17 func (b *Bitfield256) ClearBit(bv byte) { 18 b[bv>>6] &^= uint64(1) << uint64(bv&0x3f) 19 } 20 21 // GetBit returns the value of the 1<<bv bit of the bitfield (0 is false, 1 is true). 22 func (b *Bitfield256) GetBit(bv byte) bool { 23 return b[bv>>6]&(uint64(1)<<uint64(bv&0x3f)) != 0 24 } 25 26 // Equals returns true if this Bitfield256 equals the argument. 27 func (b *Bitfield256) Equals(other *Bitfield256) bool { 28 if other == nil { 29 return false 30 } 31 return *b == *other 32 } 33 34 // OnesCount returns the number of 1 bits in the bitfield. 35 func (b *Bitfield256) OnesCount() (l int) { 36 for _, g := range b { 37 if g != 0 { 38 l += bits.OnesCount64(g) 39 } 40 } 41 return 42 } 43 44 // String prints the hexadecimal representation of the bits. 45 func (b *Bitfield256) String() string { 46 return fmt.Sprintf("%0.16x%0.16x%0.16x%0.16x", b[0], b[1], b[2], b[3]) 47 } 48 49 // ToSlice returns an ordered slice of all bytes in this Bitfield256. 50 func (b *Bitfield256) ToSlice() []byte { 51 l := b.OnesCount() // faster and more accurate than repeatedly growing a slice 52 if l == 0 { 53 return []byte{} 54 } 55 slice := make([]byte, l) 56 i := 0 57 for bi, g := range b { 58 if g != 0 { 59 bx := bi << 6 60 for bit := 0; bit < 64; bit++ { 61 if g&(uint64(1)<<bit) != 0 { 62 slice[i] = byte(bx | bit) 63 i++ 64 } 65 } 66 } 67 } 68 return slice 69 } 70 71 // Mask returns how many bits, from left to right, that have the same 72 // value for all bytes represented by this Bitfield256 and a byte containing 73 // the value of those bits. 74 func (b *Bitfield256) Mask() (ones int, value byte) { 75 for testBit := 7; testBit >= 0; testBit-- { 76 hasBit := false 77 first := true 78 v := 1 << testBit 79 for i, g := range b { 80 if g != 0 { 81 bx := i << 6 // top two bits of bytes in this group 82 for bit := 0; bit < 64; bit++ { 83 if g&(uint64(1)<<bit) != 0 { 84 bv := bx | bit 85 if first { 86 first = false 87 hasBit = bv&v != 0 88 } else if hasBit != (bv&v != 0) { 89 return 7 - testBit, value 90 } 91 } 92 } 93 } 94 } 95 if hasBit { 96 value |= byte(v) 97 } 98 } 99 return 8, value 100 }