| #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 |