00001 // bitmap.cc 00002 // Routines to manage a bitmap -- an array of bits each of which 00003 // can be either on or off. Represented as an array of integers. 00004 // 00005 // Copyright (c) 1992-1996 The Regents of the University of California. 00006 // All rights reserved. See copyright.h for copyright notice and limitation 00007 // of liability and disclaimer of warranty provisions. 00008 00009 #include "copyright.h" 00010 #include "debug.h" 00011 #include "bitmap.h" 00012 00013 //---------------------------------------------------------------------- 00014 // BitMap::BitMap 00015 // Initialize a bitmap with "numItems" bits, so that every bit is clear. 00016 // it can be added somewhere on a list. 00017 // 00018 // "numItems" is the number of bits in the bitmap. 00019 //---------------------------------------------------------------------- 00020 00021 Bitmap::Bitmap(int numItems) 00022 { 00023 int i; 00024 00025 ASSERT(numItems > 0); 00026 00027 numBits = numItems; 00028 numWords = divRoundUp(numBits, BitsInWord); 00029 map = new unsigned int[numWords]; 00030 for (i = 0; i < numWords; i++) { 00031 map[i] = 0; // initialize map to keep Purify happy 00032 } 00033 for (i = 0; i < numBits; i++) { 00034 Clear(i); 00035 } 00036 } 00037 00038 //---------------------------------------------------------------------- 00039 // Bitmap::~Bitmap 00040 // De-allocate a bitmap. 00041 //---------------------------------------------------------------------- 00042 00043 Bitmap::~Bitmap() 00044 { 00045 delete map; 00046 } 00047 00048 //---------------------------------------------------------------------- 00049 // Bitmap::Set 00050 // Set the "nth" bit in a bitmap. 00051 // 00052 // "which" is the number of the bit to be set. 00053 //---------------------------------------------------------------------- 00054 00055 void 00056 Bitmap::Mark(int which) 00057 { 00058 ASSERT(which >= 0 && which < numBits); 00059 00060 map[which / BitsInWord] |= 1 << (which % BitsInWord); 00061 00062 ASSERT(Test(which)); 00063 } 00064 00065 //---------------------------------------------------------------------- 00066 // Bitmap::Clear 00067 // Clear the "nth" bit in a bitmap. 00068 // 00069 // "which" is the number of the bit to be cleared. 00070 //---------------------------------------------------------------------- 00071 00072 void 00073 Bitmap::Clear(int which) 00074 { 00075 ASSERT(which >= 0 && which < numBits); 00076 00077 map[which / BitsInWord] &= ~(1 << (which % BitsInWord)); 00078 00079 ASSERT(!Test(which)); 00080 } 00081 00082 //---------------------------------------------------------------------- 00083 // Bitmap::Test 00084 // Return TRUE if the "nth" bit is set. 00085 // 00086 // "which" is the number of the bit to be tested. 00087 //---------------------------------------------------------------------- 00088 00089 bool 00090 Bitmap::Test(int which) const 00091 { 00092 ASSERT(which >= 0 && which < numBits); 00093 00094 if (map[which / BitsInWord] & (1 << (which % BitsInWord))) { 00095 return TRUE; 00096 } else { 00097 return FALSE; 00098 } 00099 } 00100 00101 //---------------------------------------------------------------------- 00102 // Bitmap::FindAndSet 00103 // Return the number of the first bit which is clear. 00104 // As a side effect, set the bit (mark it as in use). 00105 // (In other words, find and allocate a bit.) 00106 // 00107 // If no bits are clear, return -1. 00108 //---------------------------------------------------------------------- 00109 00110 int 00111 Bitmap::FindAndSet() 00112 { 00113 for (int i = 0; i < numBits; i++) { 00114 if (!Test(i)) { 00115 Mark(i); 00116 return i; 00117 } 00118 } 00119 return -1; 00120 } 00121 00122 //---------------------------------------------------------------------- 00123 // Bitmap::NumClear 00124 // Return the number of clear bits in the bitmap. 00125 // (In other words, how many bits are unallocated?) 00126 //---------------------------------------------------------------------- 00127 00128 int 00129 Bitmap::NumClear() const 00130 { 00131 int count = 0; 00132 00133 for (int i = 0; i < numBits; i++) { 00134 if (!Test(i)) { 00135 count++; 00136 } 00137 } 00138 return count; 00139 } 00140 00141 //---------------------------------------------------------------------- 00142 // Bitmap::Print 00143 // Print the contents of the bitmap, for debugging. 00144 // 00145 // Could be done in a number of ways, but we just print the #'s of 00146 // all the bits that are set in the bitmap. 00147 //---------------------------------------------------------------------- 00148 00149 void 00150 Bitmap::Print() const 00151 { 00152 cout << "Bitmap set:\n"; 00153 for (int i = 0; i < numBits; i++) { 00154 if (Test(i)) { 00155 cout << i << ", "; 00156 } 00157 } 00158 cout << "\n"; 00159 } 00160 00161 00162 //---------------------------------------------------------------------- 00163 // Bitmap::SelfTest 00164 // Test whether this module is working. 00165 //---------------------------------------------------------------------- 00166 00167 void 00168 Bitmap::SelfTest() 00169 { 00170 int i; 00171 00172 ASSERT(numBits >= BitsInWord); // bitmap must be big enough 00173 00174 ASSERT(NumClear() == numBits); // bitmap must be empty 00175 ASSERT(FindAndSet() == 0); 00176 Mark(31); 00177 ASSERT(Test(0) && Test(31)); 00178 00179 ASSERT(FindAndSet() == 1); 00180 Clear(0); 00181 Clear(1); 00182 Clear(31); 00183 00184 for (i = 0; i < numBits; i++) { 00185 Mark(i); 00186 } 00187 ASSERT(FindAndSet() == -1); // bitmap should be full! 00188 for (i = 0; i < numBits; i++) { 00189 Clear(i); 00190 } 00191 }