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 
22 BitArray::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 
45 Size BitArray::count(const bool on) const
46 {
47  return on ? m_set : m_bitCount - m_set;
48 }
49 
50 void 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 
77 void BitArray::unset(const Size bit)
78 {
79  set(bit, false);
80 }
81 
82 bool BitArray::isSet(const Size bit) const
83 {
84  assert(bit < m_bitCount);
85 
86  return m_array[bit / 8] & (1 << (bit % 8));
87 }
88 
89 void 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 
170 void 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 
208 bool BitArray::operator[](const Size bit) const
209 {
210  return isSet(bit);
211 }
212 
213 bool BitArray::operator[](const int bit) const
214 {
215  return isSet(bit);
216 }
217 
218 inline 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 }
BitArray::set
void set(const Size bit, const bool value=true)
Sets the given bit to the given value.
Definition: BitArray.cpp:50
BitArray::isSet
bool isSet(const Size bit) const
Verify if a given bit is set.
Definition: BitArray.cpp:82
MemoryBlock::set
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
Definition: MemoryBlock.cpp:25
BitArray::setRange
void setRange(const Size from, const Size to)
Set a range of bits inside the map to 1.
Definition: BitArray.cpp:89
BitArray::m_array
u8 * m_array
Array containing the bits.
Definition: BitArray.h:186
BitArray::array
u8 * array() const
Retrieve a pointer to the internal BitArray.
Definition: BitArray.cpp:165
Assert.h
MemoryBlock.h
BitArray::BitArray
BitArray(const Size bitCount, u8 *array=ZERO)
Class constructor.
Definition: BitArray.cpp:22
BitArray::~BitArray
virtual ~BitArray()
Class destructor.
Definition: BitArray.cpp:32
BitArray::m_set
Size m_set
Set bits in the array.
Definition: BitArray.h:183
BitArray::Result
Result
Result codes.
Definition: BitArray.h:43
BitArray::Success
@ Success
Definition: BitArray.h:45
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
BitArray::setNext
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
BitArray::unset
void unset(const Size bit)
Sets the given bit to zero.
Definition: BitArray.cpp:77
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
BitArray::m_bitCount
Size m_bitCount
Total number of bits in the array.
Definition: BitArray.h:180
BitArray::count
Size count(const bool on) const
Get the number of bits in the map which have the given value.
Definition: BitArray.cpp:45
BitArray::calculateBitmapSize
Size calculateBitmapSize(const Size bitCount) const
Calculate required size of bitmap array in bytes.
Definition: BitArray.cpp:218
BitArray::m_allocated
bool m_allocated
True if m_array was allocated interally.
Definition: BitArray.h:189
assert
#define assert(exp)
Insert program diagnostics.
Definition: assert.h:60
u8
unsigned char u8
Unsigned 8-bit number.
Definition: Types.h:59
BitArray::setArray
void setArray(u8 *array, const Size bitCount=ZERO)
Use the given pointer as the BitArray buffer.
Definition: BitArray.cpp:170
BitArray::OutOfMemory
@ OutOfMemory
Definition: BitArray.h:47
BitArray::clear
void clear()
Set all bits to zero.
Definition: BitArray.cpp:199
ZERO
#define ZERO
Zero value.
Definition: Macros.h:43
BitArray.h
BitArray::size
Size size() const
Returns the maximum size of this Container.
Definition: BitArray.cpp:40
BitArray::operator[]
bool operator[](const Size bit) const
Retrieve the value of the given bit.
Definition: BitArray.cpp:208