Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/util/bitstring.h
Ir a la documentación de este archivo.
00001 // -*- C++ -*-
00002 
00003 /*
00004 
00005   Heap Layers: An Extensible Memory Allocation Infrastructure
00006   
00007   Copyright (C) 2000-2004 by Emery Berger
00008   http://www.cs.umass.edu/~emery
00009   emery@cs.umass.edu
00010   
00011   This program is free software; you can redistribute it and/or modify
00012   it under the terms of the GNU General Public License as published by
00013   the Free Software Foundation; either version 2 of the License, or
00014   (at your option) any later version.
00015   
00016   This program is distributed in the hope that it will be useful,
00017   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019   GNU General Public License for more details.
00020   
00021   You should have received a copy of the GNU General Public License
00022   along with this program; if not, write to the Free Software
00023   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025 */
00026 
00033 #ifndef _BITSTRING_H_
00034 #define _BITSTRING_H_
00035 
00036 #include <assert.h>
00037 
00038 template <int N>
00039 class BitString {
00040 public:
00041 
00042   BitString (void) {
00043     clear();
00044   }
00045 
00046   inline void clear (void) {
00047     for (int i = 0; i < NUM_ULONGS; i++) {
00048       B[i] = ALL_ALLOCATED;
00049     }
00050     firstPos = 0;
00051   }
00052 
00053   // Bit = 1 == allocated.    
00054   int allocate (int length, int alignment) {
00055     // Start at the first entry.
00056     for (int bitPos = firstPos; bitPos < N; ) {
00057       // If the whole entry here is allocated,
00058       // skip to the next one.
00059       if (B[bitPos >> SHIFTS_PER_ULONG] == ALL_ALLOCATED) {
00060         bitPos = ((bitPos >> SHIFTS_PER_ULONG) + 1) << SHIFTS_PER_ULONG;
00061         // Adjust for alignment if needed.
00062         while ((bitPos % alignment) != 0) {
00063           bitPos++;
00064         }
00065         continue;
00066       }
00067       // If this bit is set, skip to the next one.
00068       if (get(bitPos)) {
00069         bitPos += alignment;
00070         continue;
00071       }
00072       // Got something free -- let's see if we have a run of the requisite length.
00073       bool gotOne = true;
00074       for (int j = 0; j < length; j++) {
00075         if (get(bitPos + j)) {
00076           gotOne = false;
00077           bitPos += j;
00078           // Adjust for alignment if needed.
00079           while ((bitPos % alignment) != 0) {
00080             bitPos++;
00081           }
00082           break;
00083         }
00084       }
00085       if (gotOne) {
00086         // We found one - claim it!
00087         for (int j = 0; j < length; j++) {
00088           set(bitPos + j);
00089         }
00090         return bitPos;
00091       }
00092     }
00093     // Error - none found.
00094     return -1;
00095   }
00096 
00097   void free (int bitPos, int length) {
00098     for (int j = bitPos; j < bitPos + length; j++) {
00099       reset (j);
00100     }
00101   }
00102 
00103 #if 0
00104   inline int first (void) const {
00105     for (int i = 0; i < NUM_ULONGS; i++) {
00106       if (B[i] > 0) {
00107         unsigned long index = 1U << (BITS_PER_ULONG-1);
00108         for (int j = 0; j < BITS_PER_ULONG; j++) {
00109           if (B[i] & index) {
00110             return j + i * BITS_PER_ULONG;
00111           }
00112           index >>= 1;
00113         }
00114       }
00115     }
00116     return -1;
00117   }
00118 #endif
00119 
00120   inline int firstAfter (const int index) const {
00121 #if 0
00122     for (int i = index; i < N; i++ ) {
00123       int ind = i >> SHIFTS_PER_ULONG;
00124       if (B[ind] & (1U << (i & (BITS_PER_ULONG - 1)))) {
00125         return i;
00126       }
00127     }
00128     return -1;
00129 #else
00130     int indmask = index - (index >> SHIFTS_PER_ULONG) * BITS_PER_ULONG;
00131     for (int i = index >> SHIFTS_PER_ULONG; i < NUM_ULONGS; i++) {
00132       if (B[i]) {
00133         unsigned long bitval = B[i];
00134         bitval &= ~((1 << (indmask & (BITS_PER_ULONG - 1))) - 1);
00135         if (bitval) {
00136           return (i * BITS_PER_ULONG + lsb(bitval));
00137         }
00138       }
00139       indmask = indmask - BITS_PER_ULONG;
00140       if (indmask < 0) {
00141         indmask = 0;
00142       }
00143     }
00144     return -1;
00145 #endif
00146   }
00147 
00148   inline bool get (const int index) const {
00149     assert (index >= 0);
00150     assert (index < N);
00151     int ind = index >> SHIFTS_PER_ULONG;
00152     assert (ind >= 0);
00153     assert (ind < NUM_ULONGS);
00154     return (B[ind] & (1U << (index & (BITS_PER_ULONG - 1))));
00155   }
00156 
00157   inline void set (const int index) {
00158     assert (index >= 0);
00159     assert (index < N);
00160     int ind = index >> SHIFTS_PER_ULONG;
00161     assert (ind >= 0);
00162     assert (ind < NUM_ULONGS);
00163     B[ind] |= (1U << (index & (BITS_PER_ULONG - 1)));
00164     if (index < firstPos) {
00165       firstPos = index;
00166     }
00167   }
00168 
00169   inline void reset (const int index) {
00170     assert (index >= 0);
00171     assert (index < N);
00172     int ind = index >> SHIFTS_PER_ULONG;
00173     assert (ind >= 0);
00174     assert (ind < NUM_ULONGS);
00175     B[ind] &= ~(1U << (index & (BITS_PER_ULONG - 1)));
00176   }
00177 
00178   unsigned long operator() (int index) {
00179     assert (index >= 0);
00180     assert (index < NUM_ULONGS);
00181     return B[index];
00182   }
00183 
00184 
00185 private:
00186 
00187 #if 1 //  (sizeof(unsigned long),4)
00188   enum { BITS_PER_ULONG = 32 };
00189   enum { SHIFTS_PER_ULONG = 5 };
00190 #else
00191   enum { BITS_PER_ULONG = 64 };
00192   enum { SHIFTS_PER_ULONG = 6 };
00193 #endif
00194 
00195   enum { ALL_ALLOCATED = (unsigned long) -1 };
00196   enum { MAX_BITS = (N + BITS_PER_ULONG - 1) & ~(BITS_PER_ULONG - 1) };
00197   enum { NUM_ULONGS = MAX_BITS / BITS_PER_ULONG };
00198 
00199   unsigned long B[NUM_ULONGS];
00200 
00202   int firstPos;
00203 
00204   inline static int lsb (unsigned long b) {
00205     static const int index32[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };
00206     const unsigned long debruijn32 = 0x077CB531UL;
00207     b &= (unsigned long) -((signed long) b);
00208     b *= debruijn32;
00209     b >>= 27;
00210     assert (b >= 0);
00211     assert (b < 32);
00212     return index32[b];
00213   }
00214 
00215 };
00216 
00217 
00218 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'