FreeNOS
BitArray.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Assert.h"
19#include "BitArray.h"
20#include "MemoryBlock.h"
21
22BitArray::BitArray(const Size bitCount, u8 *array)
23{
24 m_array = array ? array : new u8[calculateBitmapSize(bitCount)];
25 m_allocated = (array == ZERO);
26 m_bitCount = bitCount;
27 m_set = 0;
28
29 clear();
30}
31
33{
34 if (m_allocated)
35 {
36 delete[] m_array;
37 }
38}
39
41{
42 return m_bitCount;
43}
44
45Size BitArray::count(const bool on) const
46{
47 return on ? m_set : m_bitCount - m_set;
48}
49
50void BitArray::set(const Size bit, const bool value)
51{
52 // Check if the bit is inside the array
53 if (bit >= m_bitCount)
54 {
55 return;
56 }
57
58 // Check current value
59 bool current = m_array[bit / 8] & (1 << (bit % 8));
60
61 // Update the bit only if needed (and update administration)
62 if (current != value)
63 {
64 if (value)
65 {
66 m_array[bit / 8] |= 1 << (bit % 8);
67 m_set++;
68 }
69 else
70 {
71 m_array[bit / 8] &= ~(1 << (bit % 8));
72 m_set--;
73 }
74 }
75}
76
77void BitArray::unset(const Size bit)
78{
79 set(bit, false);
80}
81
82bool BitArray::isSet(const Size bit) const
83{
84 assert(bit < m_bitCount);
85
86 return m_array[bit / 8] & (1 << (bit % 8));
87}
88
89void BitArray::setRange(const Size from, const Size to)
90{
91 for (Size i = from; i <= to; i++)
92 {
93 set(i, true);
94 }
95}
96
98 const Size count,
99 const Size start,
100 const Size boundary)
101{
102 Size from = 0, found = 0;
103
104 // Loop BitArray for unset bits
105 for (Size i = start; i < m_bitCount;)
106 {
107 // Try to fast-forward 32 bits to search
108 if (m_bitCount > 32 && i < m_bitCount - 32 && ((u32 *)m_array)[i / 32] == 0xffffffff)
109 {
110 from = found = 0;
111
112 if (i & 31)
113 i += (32 - (i % 32));
114 else
115 i += 32;
116 continue;
117 }
118 // Try to fast-forward 8 bits to search
119 else if (m_bitCount > 8 && i < m_bitCount - 8 && m_array[i / 8] == 0xff)
120 {
121 from = found = 0;
122
123 if (i & 7)
124 i += (8 - (i % 8));
125 else
126 i += 8;
127 continue;
128 }
129 else if (!isSet(i))
130 {
131 // Remember this bit
132 if (!found)
133 {
134 if (!(i % boundary))
135 {
136 from = i;
137 found = 1;
138 }
139 }
140 else
141 {
142 found++;
143 }
144
145 // Are there enough contigious bits?
146 if (found >= count)
147 {
148 setRange(from, i);
149 *bit = from;
150 return Success;
151 }
152 }
153 else
154 {
155 from = found = 0;
156 }
157
158 // Move to the next bit
159 i++;
160 }
161 // No unset bits left!
162 return OutOfMemory;
163}
164
166{
167 return m_array;
168}
169
170void BitArray::setArray(u8 *map, const Size bitCount)
171{
172 // Set bits count
173 if (bitCount)
174 {
175 m_bitCount = bitCount;
176 }
177
178 // Cleanup old array, if needed
179 if (m_array && m_allocated)
180 {
181 delete[] m_array;
182 }
183
184 // Reassign to the new map
185 m_array = map;
186 m_allocated = false;
187 m_set = 0;
188
189 // Recalculate set bits
190 for (Size i = 0; i < m_bitCount; i++)
191 {
192 if (isSet(i))
193 {
194 m_set++;
195 }
196 }
197}
198
200{
201 // Zero it
203
204 // Reset set count
205 m_set = 0;
206}
207
208bool BitArray::operator[](const Size bit) const
209{
210 return isSet(bit);
211}
212
213bool BitArray::operator[](const int bit) const
214{
215 return isSet(bit);
216}
217
218inline Size BitArray::calculateBitmapSize(const Size bitCount) const
219{
220 const Size bytes = bitCount / 8;
221
222 if (bitCount % 8)
223 return bytes + 1;
224 else
225 return bytes;
226}
void setArray(u8 *array, const Size bitCount=ZERO)
Use the given pointer as the BitArray buffer.
Definition BitArray.cpp:170
u8 * array() const
Retrieve a pointer to the internal BitArray.
Definition BitArray.cpp:165
u8 * m_array
Array containing the bits.
Definition BitArray.h:186
void set(const Size bit, const bool value=true)
Sets the given bit to the given value.
Definition BitArray.cpp:50
Size m_set
Set bits in the array.
Definition BitArray.h:183
Size calculateBitmapSize(const Size bitCount) const
Calculate required size of bitmap array in bytes.
Definition BitArray.cpp:218
Size m_bitCount
Total number of bits in the array.
Definition BitArray.h:180
bool isSet(const Size bit) const
Verify if a given bit is set.
Definition BitArray.cpp:82
bool operator[](const Size bit) const
Retrieve the value of the given bit.
Definition BitArray.cpp:208
Size count(const bool on) const
Get the number of bits in the map which have the given value.
Definition BitArray.cpp:45
void unset(const Size bit)
Sets the given bit to zero.
Definition BitArray.cpp:77
virtual ~BitArray()
Class destructor.
Definition BitArray.cpp:32
BitArray(const Size bitCount, u8 *array=ZERO)
Class constructor.
Definition BitArray.cpp:22
void clear()
Set all bits to zero.
Definition BitArray.cpp:199
void setRange(const Size from, const Size to)
Set a range of bits inside the map to 1.
Definition BitArray.cpp:89
Result setNext(Size *bit, const Size count=1, const Size offset=0, const Size boundary=1)
Sets the next unset bit(s).
Definition BitArray.cpp:97
bool m_allocated
True if m_array was allocated interally.
Definition BitArray.h:189
Size size() const
Returns the maximum size of this Container.
Definition BitArray.cpp:40
Result
Result codes.
Definition BitArray.h:44
@ OutOfMemory
Definition BitArray.h:47
@ Success
Definition BitArray.h:45
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59