-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitfield.go
133 lines (112 loc) · 3.29 KB
/
bitfield.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package bits
import (
"errors"
"strings"
)
// BitField struct holds a slice of uint64 integers for 64-bit blocks
type BitField struct {
data []uint64
size int // Number of bits the BitField can hold
}
// NewBitField creates a BitField capable of holding 'n' bits
func NewBitField(n int) *BitField {
numInts := (n + 63) / 64 // Calculate number of uint64 required
return &BitField{
data: make([]uint64, numInts),
size: n,
}
}
// SetBit sets the bit at position 'pos' to 1
func (bf *BitField) SetBit(pos int) {
index, bit := pos/64, uint(pos%64)
bf.data[index] |= (1 << bit)
}
// ClearBit clears the bit at position 'pos' (sets it to 0)
func (bf *BitField) ClearBit(pos int) {
index, bit := pos/64, uint(pos%64)
bf.data[index] &^= (1 << bit)
}
// IsSet checks if the bit at position 'pos' is set (1)
func (bf *BitField) IsSet(pos int) bool {
index, bit := pos/64, uint(pos%64)
return (bf.data[index] & (1 << bit)) != 0
}
// AllocateNextAvailableBits finds and sets the next `n` available bits, returning their positions.
// It does not require the bits to be consecutive.
func (bf *BitField) AllocateNextAvailableBits(n int) ([]int, error) {
if n <= 0 || n > bf.size {
return nil, errors.New("invalid number of bits to allocate")
}
allocated := make([]int, 0, n)
for pos := 0; pos < bf.size && len(allocated) < n; pos++ {
if !bf.IsSet(pos) {
bf.SetBit(pos)
allocated = append(allocated, pos)
}
}
if len(allocated) < n {
// Not enough available bits found
return nil, errors.New("not enough available bits")
}
return allocated, nil
}
// AllocateAvailableBitsInRange finds the next `n` available (unset) bits within a specified range [start, end).
// It does not require the bits to be consecutive.
func (bf *BitField) AllocateAvailableBitsInRange(start, end, n int) ([]int, error) {
// Validate input range
if start < 0 || end > bf.size || start >= end || n <= 0 {
return nil, errors.New("invalid input parameters")
}
availableBits := make([]int, 0, n)
for pos := start; pos < end && len(availableBits) < n; pos++ {
if !bf.IsSet(pos) {
bf.SetBit(pos)
availableBits = append(availableBits, pos)
}
}
if len(availableBits) < n {
// Not enough available bits found
return nil, errors.New("not enough available bits in range")
}
return availableBits, nil
}
// String returns a string representation of the BitField.
func (bf *BitField) String() string {
var sb strings.Builder
sb.WriteString("BitField: [")
for i := 0; i < bf.size; i++ {
if bf.IsSet(i) {
sb.WriteString("1")
} else {
sb.WriteString("0")
}
}
sb.WriteString("]")
return sb.String()
}
/*
func main() {
bitField := NewBitField(128) // Initialize bit field with 128 bits
// Set next available 5 bits
startPos, err := bitField.AllocateNextAvailableBits(5)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Next available 5 bits set starting at position %d\n", startPos)
}
// Check if the bits are set
for i := startPos; i < startPos+5; i++ {
fmt.Printf("Bit %d is set: %v\n", i, bitField.IsSet(i))
}
}
func main_1() {
// Create a BitField of size 10
bitField := NewBitField(10)
// Set bits at specific positions
bitField.SetBit(1)
bitField.SetBit(3)
bitField.SetBit(5)
// Print BitField representation
fmt.Println(bitField.String()) // Expected: BitField: [0101010000]
}
*/