diff options
author | Denis Kenzior <denkenz@gmail.com> | 2010-01-07 13:20:48 -0600 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2010-01-07 13:20:48 -0600 |
commit | af007cde6671c235f343773391ff27654d249859 (patch) | |
tree | 01fe51fdf838b9782872e6d23657984f2fbb12fb /src/idmap.c | |
parent | 6051d0bddeb3a1e82005da9aa3ef4d7bfea6888c (diff) | |
download | ofono-af007cde6671c235f343773391ff27654d249859.tar.bz2 |
Add idmap_from_range constructor
Diffstat (limited to 'src/idmap.c')
-rw-r--r-- | src/idmap.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/src/idmap.c b/src/idmap.c index f56c8e58..a42bf118 100644 --- a/src/idmap.c +++ b/src/idmap.c @@ -36,6 +36,8 @@ struct idmap { unsigned long *bits; unsigned int size; + unsigned int min; + unsigned int max; }; static inline int ffz(unsigned long word) @@ -97,35 +99,43 @@ found_middle: return result + ffz(tmp); } -struct idmap *idmap_new(unsigned int size) +struct idmap *idmap_new_from_range(unsigned int min, unsigned int max) { struct idmap *ret = g_new0(struct idmap, 1); + unsigned int size = max - min + 1; ret->bits = g_new0(unsigned long, (size + BITS_PER_LONG - 1) / BITS_PER_LONG); ret->size = size; + ret->min = min; + ret->max = max; return ret; } +struct idmap *idmap_new(unsigned int size) +{ + return idmap_new_from_range(1, size); +} + void idmap_free(struct idmap *idmap) { g_free(idmap->bits); g_free(idmap); } -void idmap_put(struct idmap *idmap, unsigned int bit) +void idmap_put(struct idmap *idmap, unsigned int id) { - unsigned int offset = (bit - 1) / BITS_PER_LONG; + unsigned int offset = (id - idmap->min) / BITS_PER_LONG; - bit -= 1; + id -= idmap->min; - if (bit > idmap->size) + if (id > idmap->size) return; - bit %= BITS_PER_LONG; + id %= BITS_PER_LONG; - idmap->bits[offset] &= ~(1 << bit); + idmap->bits[offset] &= ~(1 << id); } unsigned int idmap_alloc(struct idmap *idmap) @@ -141,18 +151,21 @@ unsigned int idmap_alloc(struct idmap *idmap) offset = bit / BITS_PER_LONG; idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG); - return bit + 1; + return bit + idmap->min; } /* - * Allocate the next bit skipping the first last bits + * Allocate the next bit skipping the ids up to and including last. If there + * is no free ids until the max id is encountered, the counter is wrapped back + * to min and the search starts again. */ unsigned int idmap_alloc_next(struct idmap *idmap, unsigned int last) { unsigned int bit; unsigned int offset; - bit = find_next_zero_bit(idmap->bits, idmap->size, last); + bit = find_next_zero_bit(idmap->bits, idmap->size, + last - idmap->min + 1); if (bit >= idmap->size) return idmap_alloc(idmap); @@ -160,5 +173,15 @@ unsigned int idmap_alloc_next(struct idmap *idmap, unsigned int last) offset = bit / BITS_PER_LONG; idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG); - return bit + 1; + return bit + idmap->min; +} + +unsigned int idmap_get_min(struct idmap *idmap) +{ + return idmap->min; +} + +unsigned int idmap_get_max(struct idmap *idmap) +{ + return idmap->max; } |