summaryrefslogtreecommitdiffstats
path: root/src/idmap.c
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2010-01-07 13:20:48 -0600
committerDenis Kenzior <denkenz@gmail.com>2010-01-07 13:20:48 -0600
commitaf007cde6671c235f343773391ff27654d249859 (patch)
tree01fe51fdf838b9782872e6d23657984f2fbb12fb /src/idmap.c
parent6051d0bddeb3a1e82005da9aa3ef4d7bfea6888c (diff)
downloadofono-af007cde6671c235f343773391ff27654d249859.tar.bz2
Add idmap_from_range constructor
Diffstat (limited to 'src/idmap.c')
-rw-r--r--src/idmap.c45
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;
}