kernel/util: Add bitmap implementation

This commit is contained in:
Pawel Dziepak 2013-10-03 04:27:49 +02:00
parent 7087b865e2
commit 149c82a8ec
4 changed files with 168 additions and 0 deletions

View File

@ -38,5 +38,23 @@ countSetBits(uint32 v)
}
static inline uint32
log2(uint32 v)
{
static const int MultiplyDeBruijnBitPosition[32] = {
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return MultiplyDeBruijnBitPosition[(uint32)(v * 0x07C4ACDDU) >> 27];
}
#endif // KERNEL_UTIL_RANDOM_H

View File

@ -0,0 +1,81 @@
/*
* Copyright 2013 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#ifndef KERNEL_UTIL_BITMAP_H
#define KERNEL_UTIL_BITMAP_H
#include <Debug.h>
#include <SupportDefs.h>
class Bitmap {
public:
Bitmap(int bitCount);
~Bitmap();
inline status_t GetInitStatus();
inline bool Get(int index) const;
inline void Set(int index);
inline void Clear(int index);
int GetHighestSet() const;
private:
status_t fInitStatus;
int fElementsCount;
int fSize;
addr_t* fBits;
static const int kBitsPerElement;
};
status_t
Bitmap::GetInitStatus()
{
return fInitStatus;
}
bool
Bitmap::Get(int index) const
{
ASSERT(index < fSize);
const int kArrayElement = index / kBitsPerElement;
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
return fBits[kArrayElement] & kBitMask;
}
void
Bitmap::Set(int index)
{
ASSERT(index < fSize);
const int kArrayElement = index / kBitsPerElement;
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
fBits[kArrayElement] |= kBitMask;
}
void
Bitmap::Clear(int index)
{
ASSERT(index < fSize);
const int kArrayElement = index / kBitsPerElement;
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
fBits[kArrayElement] &= ~addr_t(kBitMask);
}
#endif // KERNEL_UTIL_BITMAP_H

View File

@ -0,0 +1,68 @@
/*
* Copyright 2013 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#include <util/Bitmap.h>
#include <new>
#include <string.h>
#include <util/BitUtils.h>
const int Bitmap::kBitsPerElement = sizeof(addr_t) * 8;
Bitmap::Bitmap(int bitCount)
:
fInitStatus(B_OK),
fElementsCount(0),
fSize(bitCount)
{
int count = fSize + kBitsPerElement - 1;
count /= kBitsPerElement;
fBits = new(std::nothrow) addr_t[count];
if (fBits == NULL) {
fSize = 0;
fInitStatus = B_NO_MEMORY;
}
fElementsCount = count;
memset(fBits, 0, sizeof(addr_t) * count);
}
Bitmap::~Bitmap()
{
delete[] fBits;
}
int
Bitmap::GetHighestSet() const
{
int i = fElementsCount - 1;
while (i >= 0 && fBits[i] == 0)
i--;
if (i < 0)
return -1;
STATIC_ASSERT(sizeof(addr_t) == sizeof(uint64)
|| sizeof(addr_t) == sizeof(uint32));
if (sizeof(addr_t) == sizeof(uint32))
return log2(fBits[i]) + i * kBitsPerElement;
uint32 v = fBits[i] >> 32;
if (v != 0)
return log2(v) + sizeof(uint32) * 8 + i * kBitsPerElement;
return log2(fBits[i]) + i * kBitsPerElement;
}

View File

@ -4,6 +4,7 @@ UsePrivateHeaders [ FDirName kernel util ] ;
KernelMergeObject kernel_util.o :
AVLTreeBase.cpp
Bitmap.cpp
hostname.cpp
inet_addr.c
inet_ntop.c