mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 18:04:03 +00:00
lib: Convert vrf bit-map to a hash.
Memory sizes of the vrf bit-map was insane for a system with a moderate number of data on it: Zebra: VRF bit-map : 601 65536 39391944 Having a full 32bit integer bit space is problematically large, switch over to a hash to store bit data. We do not need to waste so much space. VRF bit-map : 13 8 312 Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
753e2c9152
commit
4a8bf85858
116
lib/vrf.c
116
lib/vrf.c
@ -342,91 +342,103 @@ void *vrf_info_lookup(vrf_id_t vrf_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VRF bit-map
|
* VRF hash for storing set or not.
|
||||||
*/
|
*/
|
||||||
|
struct vrf_bit_set {
|
||||||
#define VRF_BITMAP_NUM_OF_GROUPS 1024
|
vrf_id_t vrf_id;
|
||||||
#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP (UINT32_MAX / VRF_BITMAP_NUM_OF_GROUPS)
|
bool set;
|
||||||
#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
|
|
||||||
(VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
|
|
||||||
|
|
||||||
#define VRF_BITMAP_GROUP(_id) ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
|
|
||||||
#define VRF_BITMAP_BIT_OFFSET(_id) ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
|
|
||||||
|
|
||||||
#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) ((_bit_offset) / CHAR_BIT)
|
|
||||||
#define VRF_BITMAP_FLAG(_bit_offset) \
|
|
||||||
(((uint8_t)1) << ((_bit_offset) % CHAR_BIT))
|
|
||||||
|
|
||||||
struct vrf_bitmap {
|
|
||||||
uint8_t *groups[VRF_BITMAP_NUM_OF_GROUPS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned int vrf_hash_bitmap_key(void *data)
|
||||||
|
{
|
||||||
|
struct vrf_bit_set *bit = data;
|
||||||
|
|
||||||
|
return bit->vrf_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vrf_hash_bitmap_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct vrf_bit_set *bit1 = a;
|
||||||
|
const struct vrf_bit_set *bit2 = b;
|
||||||
|
|
||||||
|
return bit1->vrf_id == bit2->vrf_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *vrf_hash_bitmap_alloc(void *data)
|
||||||
|
{
|
||||||
|
struct vrf_bit_set *copy = data;
|
||||||
|
struct vrf_bit_set *bit;
|
||||||
|
|
||||||
|
bit = XMALLOC(MTYPE_VRF_BITMAP, sizeof(*bit));
|
||||||
|
bit->vrf_id = copy->vrf_id;
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vrf_hash_bitmap_free(void *data)
|
||||||
|
{
|
||||||
|
struct vrf_bit_set *bit = data;
|
||||||
|
|
||||||
|
XFREE(MTYPE_VRF_BITMAP, bit);
|
||||||
|
}
|
||||||
|
|
||||||
vrf_bitmap_t vrf_bitmap_init(void)
|
vrf_bitmap_t vrf_bitmap_init(void)
|
||||||
{
|
{
|
||||||
return (vrf_bitmap_t)XCALLOC(MTYPE_VRF_BITMAP,
|
return hash_create_size(32, vrf_hash_bitmap_key, vrf_hash_bitmap_cmp,
|
||||||
sizeof(struct vrf_bitmap));
|
"VRF BIT HASH");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vrf_bitmap_free(vrf_bitmap_t bmap)
|
void vrf_bitmap_free(vrf_bitmap_t bmap)
|
||||||
{
|
{
|
||||||
struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
|
struct hash *vrf_hash = bmap;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (bmap == VRF_BITMAP_NULL)
|
if (vrf_hash == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
|
hash_clean(vrf_hash, vrf_hash_bitmap_free);
|
||||||
if (bm->groups[i])
|
hash_free(vrf_hash);
|
||||||
XFREE(MTYPE_VRF_BITMAP, bm->groups[i]);
|
|
||||||
|
|
||||||
XFREE(MTYPE_VRF_BITMAP, bm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
|
struct vrf_bit_set lookup = { .vrf_id = vrf_id };
|
||||||
uint8_t group = VRF_BITMAP_GROUP(vrf_id);
|
struct hash *vrf_hash = bmap;
|
||||||
uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
|
struct vrf_bit_set *bit;
|
||||||
|
|
||||||
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN)
|
if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bm->groups[group] == NULL)
|
bit = hash_get(vrf_hash, &lookup, vrf_hash_bitmap_alloc);
|
||||||
bm->groups[group] = XCALLOC(MTYPE_VRF_BITMAP,
|
bit->set = true;
|
||||||
VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
|
|
||||||
|
|
||||||
SET_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
|
|
||||||
VRF_BITMAP_FLAG(offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vrf_bitmap_unset(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
void vrf_bitmap_unset(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
|
struct vrf_bit_set lookup = { .vrf_id = vrf_id };
|
||||||
uint8_t group = VRF_BITMAP_GROUP(vrf_id);
|
struct hash *vrf_hash = bmap;
|
||||||
uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
|
struct vrf_bit_set *bit;
|
||||||
|
|
||||||
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN
|
if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
|
||||||
|| bm->groups[group] == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UNSET_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
|
bit = hash_get(vrf_hash, &lookup, vrf_hash_bitmap_alloc);
|
||||||
VRF_BITMAP_FLAG(offset));
|
bit->set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vrf_bitmap_check(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
int vrf_bitmap_check(vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
|
struct vrf_bit_set lookup = { .vrf_id = vrf_id };
|
||||||
uint8_t group = VRF_BITMAP_GROUP(vrf_id);
|
struct hash *vrf_hash = bmap;
|
||||||
uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
|
struct vrf_bit_set *bit;
|
||||||
|
|
||||||
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN
|
if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
|
||||||
|| bm->groups[group] == NULL)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return CHECK_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
|
bit = hash_lookup(vrf_hash, &lookup);
|
||||||
VRF_BITMAP_FLAG(offset))
|
if (bit)
|
||||||
? 1
|
return bit->set;
|
||||||
: 0;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vrf_autocomplete(vector comps, struct cmd_token *token)
|
static void vrf_autocomplete(vector comps, struct cmd_token *token)
|
||||||
|
Loading…
Reference in New Issue
Block a user