blob: aeeaf88065d30b183ae7d03e104a4bd3458cde22 [file] [log] [blame]
#ifndef BTREE_H
#define BTREE_H
#include "kerncompat.h"
/*
* B+Tree node format:
* [key0, key1, ..., keyN] [val0, val1, ..., valN]
* Each key is an array of unsigned longs, head->no_longs in total.
* Total number of keys and vals (N) is head->no_pairs.
*/
struct btree_head {
unsigned long *node;
int height;
};
struct btree_geo {
int keylen;
int no_pairs;
};
extern struct btree_geo btree_geo32;
extern struct btree_geo btree_geo64;
extern struct btree_geo btree_geo128;
struct btree_headl { struct btree_head h; };
struct btree_head32 { struct btree_head h; };
struct btree_head64 { struct btree_head h; };
struct btree_head128 { struct btree_head h; };
/*
* These couple of functions are all there is to it. The rest of this header
* consists only of wrappers that try to add some typesafety, make the code
* a little self-documenting and generally be nice to people.
*/
void btree_free(void *element, void *pool_data);
void btree_init(struct btree_head *head);
void *btree_lookup(struct btree_head *head, struct btree_geo *geo,
unsigned long *key);
int btree_insert(struct btree_head *head, struct btree_geo *geo,
unsigned long *key, void *val);
void *btree_remove(struct btree_head *head, struct btree_geo *geo,
unsigned long *key);
int btree_merge(struct btree_head *target, struct btree_head *victim,
struct btree_geo *geo, unsigned long *duplicate);
unsigned long *btree_last(struct btree_head *head, struct btree_geo *geo);
size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
long opaque,
void (*func)(void *elem, long opaque, unsigned long *key,
size_t index, void *func2), void *func2);
size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
long opaque,
void (*func)(void *elem, long opaque, unsigned long *key,
size_t index, void *func2), void *func2);
/* key is unsigned long */
static inline void btree_initl(struct btree_headl *head)
{
btree_init(&head->h);
}
static inline void *btree_lookupl(struct btree_headl *head, unsigned long key)
{
return btree_lookup(&head->h, &btree_geo32, &key);
}
static inline int btree_insertl(struct btree_headl *head, unsigned long key,
void *val)
{
return btree_insert(&head->h, &btree_geo32, &key, val);
}
static inline void *btree_removel(struct btree_headl *head, unsigned long key)
{
return btree_remove(&head->h, &btree_geo32, &key);
}
static inline int btree_mergel(struct btree_headl *target,
struct btree_headl *victim)
{
unsigned long scratch;
return btree_merge(&target->h, &victim->h, &btree_geo32, &scratch);
}
void visitorl(void *elem, long opaque, unsigned long *key, size_t index,
void *__func);
typedef void (*visitorl_t)(void *elem, long opaque, unsigned long key,
size_t index);
static inline size_t btree_visitorl(struct btree_headl *head, long opaque,
visitorl_t func2)
{
return btree_visitor(&head->h, &btree_geo32, opaque, visitorl, func2);
}
static inline size_t btree_grim_visitorl(struct btree_headl *head, long opaque,
visitorl_t func2)
{
return btree_grim_visitor(&head->h, &btree_geo32, opaque, visitorl, func2);
}
/* key is u32 */
static inline void btree_init32(struct btree_head32 *head)
{
btree_init(&head->h);
}
static inline void *btree_lookup32(struct btree_head32 *head, u32 _key)
{
unsigned long key = _key;
return btree_lookup(&head->h, &btree_geo32, &key);
}
static inline int btree_insert32(struct btree_head32 *head, u32 _key,
void *val)
{
unsigned long key = _key;
return btree_insert(&head->h, &btree_geo32, (unsigned long *)&key, val);
}
static inline void *btree_remove32(struct btree_head32 *head, u32 _key)
{
unsigned long key = _key;
return btree_remove(&head->h, &btree_geo32, (unsigned long *)&key);
}
static inline int btree_merge32(struct btree_head32 *target,
struct btree_head32 *victim)
{
unsigned long scratch;
return btree_merge(&target->h, &victim->h, &btree_geo32, &scratch);
}
void visitor32(void *elem, long opaque, unsigned long *__key, size_t index,
void *__func);
typedef void (*visitor32_t)(void *elem, long opaque, u32 key, size_t index);
static inline size_t btree_visitor32(struct btree_head32 *head, long opaque,
visitor32_t func2)
{
return btree_visitor(&head->h, &btree_geo32, opaque, visitor32, func2);
}
static inline size_t btree_grim_visitor32(struct btree_head32 *head, long opaque,
visitor32_t func2)
{
return btree_grim_visitor(&head->h, &btree_geo32, opaque, visitor32, func2);
}
/* key is u64 */
static inline void btree_init64(struct btree_head64 *head)
{
btree_init(&head->h);
}
static inline void *btree_lookup64(struct btree_head64 *head, u64 key)
{
return btree_lookup(&head->h, &btree_geo64, (unsigned long *)&key);
}
static inline int btree_insert64(struct btree_head64 *head, u64 key,
void *val)
{
return btree_insert(&head->h, &btree_geo64, (unsigned long *)&key, val);
}
static inline void *btree_remove64(struct btree_head64 *head, u64 key)
{
return btree_remove(&head->h, &btree_geo64, (unsigned long *)&key);
}
static inline int btree_merge64(struct btree_head64 *target,
struct btree_head64 *victim)
{
u64 scratch;
return btree_merge(&target->h, &victim->h, &btree_geo64,
(unsigned long *)&scratch);
}
void visitor64(void *elem, long opaque, unsigned long *__key, size_t index,
void *__func);
typedef void (*visitor64_t)(void *elem, long opaque, u64 key, size_t index);
static inline size_t btree_visitor64(struct btree_head64 *head, long opaque,
visitor64_t func2)
{
return btree_visitor(&head->h, &btree_geo64, opaque, visitor64, func2);
}
static inline size_t btree_grim_visitor64(struct btree_head64 *head, long opaque,
visitor64_t func2)
{
return btree_grim_visitor(&head->h, &btree_geo64, opaque, visitor64, func2);
}
/* key is 128bit (two u64) */
static inline void btree_init128(struct btree_head128 *head)
{
btree_init(&head->h);
}
static inline void *btree_lookup128(struct btree_head128 *head, u64 k1, u64 k2)
{
u64 key[2] = {k1, k2};
return btree_lookup(&head->h, &btree_geo128, (unsigned long *)&key);
}
static inline int btree_insert128(struct btree_head128 *head, u64 k1, u64 k2,
void *val)
{
u64 key[2] = {k1, k2};
return btree_insert(&head->h, &btree_geo128, (unsigned long *)&key, val);
}
static inline void *btree_remove128(struct btree_head128 *head, u64 k1, u64 k2)
{
u64 key[2] = {k1, k2};
return btree_remove(&head->h, &btree_geo128, (unsigned long *)&key);
}
static inline void btree_last128(struct btree_head128 *head, u64 *k1, u64 *k2)
{
u64 *key = (u64 *)btree_last(&head->h, &btree_geo128);
if (key) {
*k1 = key[0];
*k2 = key[1];
} else {
*k1 = 0;
*k2 = 0;
}
}
static inline int btree_merge128(struct btree_head128 *target,
struct btree_head128 *victim)
{
u64 scratch[2];
return btree_merge(&target->h, &victim->h, &btree_geo128,
(unsigned long *)scratch);
}
void visitor128(void *elem, long opaque, unsigned long *__key, size_t index,
void *__func);
typedef void (*visitor128_t)(void *elem, long opaque, u64 key1, u64 key2,
size_t index);
static inline size_t btree_visitor128(struct btree_head128 *head, long opaque,
visitor128_t func2)
{
return btree_visitor(&head->h, &btree_geo128, opaque, visitor128, func2);
}
static inline size_t btree_grim_visitor128(struct btree_head128 *head, long opaque,
visitor128_t func2)
{
return btree_grim_visitor(&head->h, &btree_geo128, opaque, visitor128, func2);
}
#endif