@@ -1,25 +0,0 @@ | |||
#ifndef L2_BITMAP_H | |||
#define L2_BITMAP_H | |||
#include <stdlib.h> | |||
#include <stdint.h> | |||
typedef long long int l2_bitmap_entry; | |||
struct l2_bitmap { | |||
l2_bitmap_entry *tables; | |||
size_t tableslen; | |||
size_t currtable; | |||
l2_bitmap_entry *dirs; | |||
size_t dirslen; | |||
size_t currdir; | |||
}; | |||
void l2_bitmap_init(struct l2_bitmap *bm); | |||
void l2_bitmap_free(struct l2_bitmap *bm); | |||
int l2_bitmap_get(struct l2_bitmap *bm, size_t id); | |||
size_t l2_bitmap_set_next(struct l2_bitmap *bm); | |||
void l2_bitmap_unset(struct l2_bitmap *bm, size_t id); | |||
#endif |
@@ -0,0 +1,25 @@ | |||
#ifndef L2_BITSET_H | |||
#define L2_BITSET_H | |||
#include <stdlib.h> | |||
#include <stdint.h> | |||
typedef long long int l2_bitset_entry; | |||
struct l2_bitset { | |||
l2_bitset_entry *tables; | |||
size_t tableslen; | |||
size_t currtable; | |||
l2_bitset_entry *dirs; | |||
size_t dirslen; | |||
size_t currdir; | |||
}; | |||
void l2_bitset_init(struct l2_bitset *bs); | |||
void l2_bitset_free(struct l2_bitset *bs); | |||
int l2_bitset_get(struct l2_bitset *bs, size_t id); | |||
size_t l2_bitset_set_next(struct l2_bitset *bs); | |||
void l2_bitset_unset(struct l2_bitset *bs, size_t id); | |||
#endif |
@@ -1,125 +0,0 @@ | |||
#include "bitmap.h" | |||
#include <string.h> | |||
#include <strings.h> | |||
#include <limits.h> | |||
#include <stdio.h> | |||
#define ENTSIZ (sizeof(l2_bitmap_entry) * CHAR_BIT) | |||
static l2_bitmap_entry first_unset_bit(l2_bitmap_entry n) { | |||
return ~n & (n + 1); | |||
} | |||
#if 0 && defined(__GLIBC__) && ( \ | |||
(__GLIBC__>= 2 && __GLIBC_MINOR__ >= 27) || \ | |||
_GNU_SOURCE) | |||
#define first_set ffsll | |||
#else | |||
static int first_set(l2_bitmap_entry n) { | |||
if (n == 0) { | |||
return 0; | |||
} | |||
int num = 1; | |||
while ((n & 1) == 0) { | |||
n >>= 1; | |||
num += 1; | |||
} | |||
return num; | |||
} | |||
#endif | |||
static void expand_tables(struct l2_bitmap *bm) { | |||
while (bm->currtable >= bm->tableslen) { | |||
bm->tables = realloc(bm->tables, bm->tableslen * 2 * sizeof(*bm->tables)); | |||
memset(bm->tables + bm->tableslen, 0, sizeof(*bm->tables) * bm->tableslen); | |||
bm->tableslen *= 2; | |||
} | |||
} | |||
void l2_bitmap_init(struct l2_bitmap *bm) { | |||
bm->tableslen = 4; | |||
bm->tables = calloc(bm->tableslen, sizeof(*bm->tables)); | |||
bm->currtable = 0; | |||
bm->dirslen = 1; | |||
bm->dirs = calloc(bm->dirslen, sizeof(*bm->dirs)); | |||
bm->currdir = 0; | |||
} | |||
void l2_bitmap_free(struct l2_bitmap *bm) { | |||
free(bm->tables); | |||
free(bm->dirs); | |||
} | |||
int l2_bitmap_get(struct l2_bitmap *bm, size_t id) { | |||
size_t tblidx = id / ENTSIZ; | |||
size_t tblbit = id % ENTSIZ; | |||
if (tblidx >= bm->tableslen) { | |||
return 0; | |||
} | |||
return !!(bm->tables[tblidx] & (l2_bitmap_entry)1 << tblbit); | |||
} | |||
size_t l2_bitmap_set_next(struct l2_bitmap *bm) { | |||
l2_bitmap_entry *table = &bm->tables[bm->currtable]; | |||
l2_bitmap_entry bit = first_unset_bit(*table); | |||
*table |= bit; | |||
size_t ret = bm->currtable * ENTSIZ + first_set(bit) - 1; | |||
// Still free space? | |||
if (*table != ~(l2_bitmap_entry)0) { | |||
return ret; | |||
} | |||
// Ok, this entry is full then... | |||
l2_bitmap_entry *dir = &bm->dirs[bm->currdir]; | |||
*dir |= (l2_bitmap_entry)1 << (bm->currtable % ENTSIZ); | |||
// Is there still space in this directory? | |||
if (*dir != ~(l2_bitmap_entry)0) { | |||
bm->currtable = bm->currdir * ENTSIZ + first_set(first_unset_bit(*dir)) - 1; | |||
expand_tables(bm); | |||
return ret; | |||
} | |||
// Is there a directory with free space? | |||
for (size_t i = 0; i < bm->dirslen; ++i) { | |||
dir = &bm->dirs[i]; | |||
if (*dir == ~(l2_bitmap_entry)0) { | |||
continue; | |||
} | |||
bm->currdir = i; | |||
bm->currtable = bm->currdir * ENTSIZ + first_set(first_unset_bit(*dir)) - 1; | |||
expand_tables(bm); | |||
return ret; | |||
} | |||
// Ok, we gotta make a new dir then | |||
bm->currdir = bm->dirslen; | |||
bm->currtable = bm->currdir * ENTSIZ; | |||
bm->dirs = realloc(bm->dirs, bm->dirslen * 2 * sizeof(*bm->dirs)); | |||
memset(bm->dirs + bm->dirslen, 0, sizeof(*bm->dirs) * bm->dirslen); | |||
bm->dirslen *= 2; | |||
expand_tables(bm); | |||
return ret; | |||
} | |||
void l2_bitmap_unset(struct l2_bitmap *bm, size_t id) { | |||
size_t tblidx = id / ENTSIZ; | |||
size_t tblbit = id % ENTSIZ; | |||
size_t diridx = id / (ENTSIZ * ENTSIZ); | |||
size_t dirbit = (id / ENTSIZ) % ENTSIZ; | |||
if (tblidx >= bm->tableslen) { | |||
return; | |||
} | |||
bm->tables[tblidx] &= ~((l2_bitmap_entry)1 << tblbit); | |||
bm->dirs[diridx] &= ~((l2_bitmap_entry)1 << dirbit); | |||
} |
@@ -0,0 +1,125 @@ | |||
#include "bitset.h" | |||
#include <string.h> | |||
#include <strings.h> | |||
#include <limits.h> | |||
#include <stdio.h> | |||
#define ENTSIZ (sizeof(l2_bitset_entry) * CHAR_BIT) | |||
static l2_bitset_entry first_unset_bit(l2_bitset_entry n) { | |||
return ~n & (n + 1); | |||
} | |||
#if 0 && defined(__GLIBC__) && ( \ | |||
(__GLIBC__>= 2 && __GLIBC_MINOR__ >= 27) || \ | |||
_GNU_SOURCE) | |||
#define first_set ffsll | |||
#else | |||
static int first_set(l2_bitset_entry n) { | |||
if (n == 0) { | |||
return 0; | |||
} | |||
int num = 1; | |||
while ((n & 1) == 0) { | |||
n >>= 1; | |||
num += 1; | |||
} | |||
return num; | |||
} | |||
#endif | |||
static void expand_tables(struct l2_bitset *bs) { | |||
while (bs->currtable >= bs->tableslen) { | |||
bs->tables = realloc(bs->tables, bs->tableslen * 2 * sizeof(*bs->tables)); | |||
memset(bs->tables + bs->tableslen, 0, sizeof(*bs->tables) * bs->tableslen); | |||
bs->tableslen *= 2; | |||
} | |||
} | |||
void l2_bitset_init(struct l2_bitset *bs) { | |||
bs->tableslen = 4; | |||
bs->tables = calloc(bs->tableslen, sizeof(*bs->tables)); | |||
bs->currtable = 0; | |||
bs->dirslen = 1; | |||
bs->dirs = calloc(bs->dirslen, sizeof(*bs->dirs)); | |||
bs->currdir = 0; | |||
} | |||
void l2_bitset_free(struct l2_bitset *bs) { | |||
free(bs->tables); | |||
free(bs->dirs); | |||
} | |||
int l2_bitset_get(struct l2_bitset *bs, size_t id) { | |||
size_t tblidx = id / ENTSIZ; | |||
size_t tblbit = id % ENTSIZ; | |||
if (tblidx >= bs->tableslen) { | |||
return 0; | |||
} | |||
return !!(bs->tables[tblidx] & (l2_bitset_entry)1 << tblbit); | |||
} | |||
size_t l2_bitset_set_next(struct l2_bitset *bs) { | |||
l2_bitset_entry *table = &bs->tables[bs->currtable]; | |||
l2_bitset_entry bit = first_unset_bit(*table); | |||
*table |= bit; | |||
size_t ret = bs->currtable * ENTSIZ + first_set(bit) - 1; | |||
// Still free space? | |||
if (*table != ~(l2_bitset_entry)0) { | |||
return ret; | |||
} | |||
// Ok, this entry is full then... | |||
l2_bitset_entry *dir = &bs->dirs[bs->currdir]; | |||
*dir |= (l2_bitset_entry)1 << (bs->currtable % ENTSIZ); | |||
// Is there still space in this directory? | |||
if (*dir != ~(l2_bitset_entry)0) { | |||
bs->currtable = bs->currdir * ENTSIZ + first_set(first_unset_bit(*dir)) - 1; | |||
expand_tables(bs); | |||
return ret; | |||
} | |||
// Is there a directory with free space? | |||
for (size_t i = 0; i < bs->dirslen; ++i) { | |||
dir = &bs->dirs[i]; | |||
if (*dir == ~(l2_bitset_entry)0) { | |||
continue; | |||
} | |||
bs->currdir = i; | |||
bs->currtable = bs->currdir * ENTSIZ + first_set(first_unset_bit(*dir)) - 1; | |||
expand_tables(bs); | |||
return ret; | |||
} | |||
// Ok, we gotta make a new dir then | |||
bs->currdir = bs->dirslen; | |||
bs->currtable = bs->currdir * ENTSIZ; | |||
bs->dirs = realloc(bs->dirs, bs->dirslen * 2 * sizeof(*bs->dirs)); | |||
memset(bs->dirs + bs->dirslen, 0, sizeof(*bs->dirs) * bs->dirslen); | |||
bs->dirslen *= 2; | |||
expand_tables(bs); | |||
return ret; | |||
} | |||
void l2_bitset_unset(struct l2_bitset *bs, size_t id) { | |||
size_t tblidx = id / ENTSIZ; | |||
size_t tblbit = id % ENTSIZ; | |||
size_t diridx = id / (ENTSIZ * ENTSIZ); | |||
size_t dirbit = (id / ENTSIZ) % ENTSIZ; | |||
if (tblidx >= bs->tableslen) { | |||
return; | |||
} | |||
bs->tables[tblidx] &= ~((l2_bitset_entry)1 << tblbit); | |||
bs->dirs[diridx] &= ~((l2_bitset_entry)1 << dirbit); | |||
} |