]>
git.ipfire.org Git - thirdparty/bird.git/blob - lib/bitmap.c
2 * BIRD Library -- Bitmaps
4 * (c) 2019 Ondrej Zajicek <santiago@crfreenet.org>
5 * (c) 2019 CZ.NIC z.s.p.o.
7 * Can be freely distributed and used under the terms of the GNU GPL.
12 #include "nest/bird.h"
13 #include "lib/bitmap.h"
14 #include "lib/bitops.h"
15 #include "lib/resource.h"
23 bmap_init(struct bmap
*b
, pool
*p
, uint size
)
25 b
->size
= BIRD_ALIGN(size
, 4);
26 b
->data
= mb_allocz(p
, b
->size
);
30 bmap_reset(struct bmap
*b
, uint size
)
32 b
->size
= BIRD_ALIGN(size
, 4);
33 memset(b
->data
, 0, b
->size
);
37 bmap_grow(struct bmap
*b
, uint need
)
39 uint size
= b
->size
* 2;
43 uint old_size
= b
->size
;
45 b
->data
= mb_realloc(b
->data
, b
->size
);
47 ASSERT(size
>= old_size
);
48 memset(b
->data
+ (old_size
/ 4), 0, size
- old_size
);
52 bmap_free(struct bmap
*b
)
65 #define B256_SIZE(b) BIRD_ALIGN(b, 32)
66 #define B256_STEP(b) (BIRD_ALIGN(b, 8192) >> 8)
69 hmap_init(struct hmap
*b
, pool
*p
, uint size
)
71 b
->size
[0] = B256_SIZE(size
);
72 b
->size
[1] = B256_STEP(b
->size
[0]);
73 b
->size
[2] = B256_STEP(b
->size
[1]);
74 b
->size
[3] = sizeof(b
->root
);
76 b
->data
[0] = mb_allocz(p
, b
->size
[0]);
77 b
->data
[1] = mb_allocz(p
, b
->size
[1]);
78 b
->data
[2] = mb_allocz(p
, b
->size
[2]);
81 memset(b
->root
, 0, sizeof(b
->root
));
85 hmap_grow(struct hmap
*b
, uint need
)
87 uint size
= b
->size
[0] * 2;
91 for (uint i
= 0; i
< 3; i
++)
93 uint old_size
= b
->size
[i
];
95 b
->data
[i
] = mb_realloc(b
->data
[i
], b
->size
[i
]);
97 ASSERT(size
>= old_size
);
98 memset(b
->data
[i
] + (old_size
/ 4), 0, size
- old_size
);
100 size
= B256_STEP(size
);
105 hmap_free(struct hmap
*b
)
111 memset(b
, 0, sizeof(struct hmap
));
117 for (int i
= 0; i
< 8; i
++)
125 hmap_set(struct hmap
*b
, uint n
)
127 if (n
>= hmap_max(b
))
128 hmap_grow(b
, n
/8 + 1);
130 for (int i
= 0; i
< 4; i
++)
132 BIT32_SET(b
->data
[i
], n
);
135 /* Continue if all bits in 256-bit block are set */
136 if (! b256_and(b
->data
[i
] + 8*n
))
142 hmap_clear(struct hmap
*b
, uint n
)
144 if (n
>= hmap_max(b
))
147 for (int i
= 0; i
< 4; i
++)
149 BIT32_CLR(b
->data
[i
], n
);
155 b256_first_zero(u32
*p
)
157 for (int i
= 0; i
< 8; i
++)
159 return 32*i
+ u32_ctz(~p
[i
]);
165 hmap_first_zero(struct hmap
*b
)
169 for (int i
= 3; i
>= 0; i
--)
171 if (32*n
>= b
->size
[i
])
174 u32
*p
= b
->data
[i
] + 8*n
;
176 n
= (n
<< 8) + b256_first_zero(p
);
183 hmap_check(struct hmap
*b
)
185 for (int i
= 0; i
< 2; i
++)
187 int max
= b
->size
[i
] / 32;
189 for (int j
= 0; j
< max
; j
++)
191 int x
= b256_and(b
->data
[i
] + 8*j
);
192 int y
= !!BIT32_TEST(b
->data
[i
+1], j
);
194 bug("Inconsistent data on %d:%d (%d vs %d)", i
, j
, x
, y
);