00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00037 #ifndef _bit_array_h_
00038 #define _bit_array_h_
00039
00040 #include "common.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049 typedef unsigned long bit_array_t;
00050
00051 #if LONG_MAX == 0x7fffffffL
00052 #if CHAR_BIT == 8
00053 #define BIT_ARRAY_BITSHIFT (2 + 3)
00054 #elif CHAR_BIT == 16
00055 #define BIT_ARRAY_BITSHIFT (2 + 4)
00056 #else
00057 #error "Unsupported size of char"
00058 #endif
00059 #elif (ULONG_MAX >> 31) > 0xffffffffUL
00060 #if CHAR_BIT == 8
00061 #define BIT_ARRAY_BITSHIFT (3 + 3)
00062 #elif CHAR_BIT == 16
00063 #define BIT_ARRAY_BITSHIFT (3 + 4)
00064 #else
00065 #error "Unsupported size of char"
00066 #endif
00067 #endif
00068
00069 #define BIT_ARRAY_BITSIZE (CHAR_BIT * sizeof(bit_array_t))
00070 #define BIT_ARRAY_BITMASK (BIT_ARRAY_BITSIZE - 1)
00071 #define BIT_ARRAY_WORD(base, i) base[(i) >> BIT_ARRAY_BITSHIFT]
00072 #define BIT_ARRAY_BIT(base, i) (1UL << ((i) & BIT_ARRAY_BITMASK))
00073
00080 #define BIT_ARRAY_SIZE(n) \
00081 ((n) / (CHAR_BIT * sizeof(bit_array_t)) + \
00082 ((n) % (CHAR_BIT * sizeof(bit_array_t)) ? 1 : 0))
00083
00091 #define BIT_ARRAY_BYTE_SIZE(n) (BIT_ARRAY_SIZE(n) * sizeof (bit_array_t))
00092
00102 static inline bit_array_t *
00103 bit_array_realloc(bit_array_t *base, size_t n)
00104 {
00105 size_t size;
00106
00107 STATIC_ASSERT(0 == (BIT_ARRAY_BITSIZE & BIT_ARRAY_BITMASK));
00108
00109 size = BIT_ARRAY_BYTE_SIZE(n);
00110 return g_realloc(base, size);
00111 }
00112
00113
00118 static inline void
00119 bit_array_set(bit_array_t *base, size_t i)
00120 {
00121 BIT_ARRAY_WORD(base, i) |= BIT_ARRAY_BIT(base, i);
00122 }
00123
00128 static inline void
00129 bit_array_clear(bit_array_t *base, size_t i)
00130 {
00131 BIT_ARRAY_WORD(base, i) &= ~BIT_ARRAY_BIT(base, i);
00132 }
00133
00140 static inline gboolean
00141 bit_array_flip(bit_array_t *base, size_t i)
00142 {
00143 return BIT_ARRAY_WORD(base, i) ^= BIT_ARRAY_BIT(base, i);
00144 }
00145
00151 static inline gboolean
00152 bit_array_get(const bit_array_t *base, size_t i)
00153 {
00154 return 0 != (BIT_ARRAY_WORD(base, i) & BIT_ARRAY_BIT(base, i));
00155 }
00156
00166 static inline void
00167 bit_array_clear_range(bit_array_t *base, size_t from, size_t to)
00168 {
00169 size_t i;
00170
00171 g_assert(from <= to);
00172
00173 for (i = from; i <= to; ) {
00174 if (0 == (i & BIT_ARRAY_BITMASK)) {
00175 size_t n = (to - i) >> BIT_ARRAY_BITSHIFT;
00176
00177 if (n != 0) {
00178 size_t j = i >> BIT_ARRAY_BITSHIFT;
00179
00180 i += n * BIT_ARRAY_BITSIZE;
00181 do {
00182 base[j++] = 0;
00183 } while (--n != 0);
00184 continue;
00185 }
00186 }
00187 bit_array_clear(base, i++);
00188 }
00189 }
00190
00200 static inline void
00201 bit_array_set_range(bit_array_t *base, size_t from, size_t to)
00202 {
00203 size_t i;
00204
00205 g_assert(from <= to);
00206
00207 for (i = from; i <= to; ) {
00208 if (0 == (i & BIT_ARRAY_BITMASK)) {
00209 size_t n = (to - i) >> BIT_ARRAY_BITSHIFT;
00210
00211 if (n != 0) {
00212 size_t j = i >> BIT_ARRAY_BITSHIFT;
00213
00214 i += n * BIT_ARRAY_BITSIZE;
00215 do {
00216 base[j++] = (bit_array_t) -1;
00217 } while (--n != 0);
00218 continue;
00219 }
00220 }
00221 bit_array_set(base, i++);
00222 }
00223 }
00224
00234 static inline size_t
00235 bit_array_first_clear(const bit_array_t *base, size_t from, size_t to)
00236 {
00237 size_t i;
00238
00239 g_assert(from <= to);
00240
00241 for (i = from; i <= to; i++) {
00242 if (!bit_array_get(base, i))
00243 return i;
00244 }
00245
00246 for (i = from; i <= to; ) {
00247 if (0 == (i & BIT_ARRAY_BITMASK)) {
00248 size_t n = (to - i) >> BIT_ARRAY_BITSHIFT;
00249
00250 if (n != 0) {
00251 size_t j = i >> BIT_ARRAY_BITSHIFT;
00252
00253 while (n-- > 0) {
00254 if (base[j++] != (bit_array_t) -1) {
00255 bit_array_t value = base[j - 1];
00256 while (value & 0x1) {
00257 value >>= 1;
00258 i++;
00259 }
00260 return i;
00261 }
00262 i += BIT_ARRAY_BITSIZE;
00263 }
00264 }
00265 }
00266 if (!bit_array_get(base, i))
00267 return i;
00268 i++;
00269 }
00270
00271 return (size_t) -1;
00272 }
00273
00274 #undef BIT_ARRAY_BIT
00275 #undef BIT_ARRAY_BITSIZE
00276 #undef BIT_ARRAY_BITMASK
00277 #undef BIT_ARRAY_BITSHIFT
00278 #undef BIT_ARRAY_WORD
00279
00280 #endif
00281