Files
ios2024/code/lib/bitmap.cc

192 lines
4.6 KiB
C++

// bitmap.cc
// Routines to manage a bitmap -- an array of bits each of which
// can be either on or off. Represented as an array of integers.
//
// Copyright (c) 1992-1996 The Regents of the University of California.
// All rights reserved. See copyright.h for copyright notice and limitation
// of liability and disclaimer of warranty provisions.
#include "copyright.h"
#include "debug.h"
#include "bitmap.h"
//----------------------------------------------------------------------
// BitMap::BitMap
// Initialize a bitmap with "numItems" bits, so that every bit is clear.
// it can be added somewhere on a list.
//
// "numItems" is the number of bits in the bitmap.
//----------------------------------------------------------------------
Bitmap::Bitmap(int numItems)
{
int i;
ASSERT(numItems > 0);
numBits = numItems;
numWords = divRoundUp(numBits, BitsInWord);
map = new unsigned int[numWords];
for (i = 0; i < numWords; i++) {
map[i] = 0; // initialize map to keep Purify happy
}
for (i = 0; i < numBits; i++) {
Clear(i);
}
}
//----------------------------------------------------------------------
// Bitmap::~Bitmap
// De-allocate a bitmap.
//----------------------------------------------------------------------
Bitmap::~Bitmap()
{
delete map;
}
//----------------------------------------------------------------------
// Bitmap::Set
// Set the "nth" bit in a bitmap.
//
// "which" is the number of the bit to be set.
//----------------------------------------------------------------------
void
Bitmap::Mark(int which)
{
ASSERT(which >= 0 && which < numBits);
map[which / BitsInWord] |= 1 << (which % BitsInWord);
ASSERT(Test(which));
}
//----------------------------------------------------------------------
// Bitmap::Clear
// Clear the "nth" bit in a bitmap.
//
// "which" is the number of the bit to be cleared.
//----------------------------------------------------------------------
void
Bitmap::Clear(int which)
{
ASSERT(which >= 0 && which < numBits);
map[which / BitsInWord] &= ~(1 << (which % BitsInWord));
ASSERT(!Test(which));
}
//----------------------------------------------------------------------
// Bitmap::Test
// Return TRUE if the "nth" bit is set.
//
// "which" is the number of the bit to be tested.
//----------------------------------------------------------------------
bool
Bitmap::Test(int which) const
{
ASSERT(which >= 0 && which < numBits);
if (map[which / BitsInWord] & (1 << (which % BitsInWord))) {
return TRUE;
} else {
return FALSE;
}
}
//----------------------------------------------------------------------
// Bitmap::FindAndSet
// Return the number of the first bit which is clear.
// As a side effect, set the bit (mark it as in use).
// (In other words, find and allocate a bit.)
//
// If no bits are clear, return -1.
//----------------------------------------------------------------------
int
Bitmap::FindAndSet()
{
for (int i = 0; i < numBits; i++) {
if (!Test(i)) {
Mark(i);
return i;
}
}
return -1;
}
//----------------------------------------------------------------------
// Bitmap::NumClear
// Return the number of clear bits in the bitmap.
// (In other words, how many bits are unallocated?)
//----------------------------------------------------------------------
int
Bitmap::NumClear() const
{
int count = 0;
for (int i = 0; i < numBits; i++) {
if (!Test(i)) {
count++;
}
}
return count;
}
//----------------------------------------------------------------------
// Bitmap::Print
// Print the contents of the bitmap, for debugging.
//
// Could be done in a number of ways, but we just print the #'s of
// all the bits that are set in the bitmap.
//----------------------------------------------------------------------
void
Bitmap::Print() const
{
cout << "Bitmap set:\n";
for (int i = 0; i < numBits; i++) {
if (Test(i)) {
cout << i << ", ";
}
}
cout << "\n";
}
//----------------------------------------------------------------------
// Bitmap::SelfTest
// Test whether this module is working.
//----------------------------------------------------------------------
void
Bitmap::SelfTest()
{
int i;
ASSERT(numBits >= BitsInWord); // bitmap must be big enough
ASSERT(NumClear() == numBits); // bitmap must be empty
ASSERT(FindAndSet() == 0);
Mark(31);
ASSERT(Test(0) && Test(31));
ASSERT(FindAndSet() == 1);
Clear(0);
Clear(1);
Clear(31);
for (i = 0; i < numBits; i++) {
Mark(i);
}
ASSERT(FindAndSet() == -1); // bitmap should be full!
for (i = 0; i < numBits; i++) {
Clear(i);
}
}