44 #include <linux/kernel.h>
45 #include <linux/slab.h>
46 #include <linux/module.h>
48 #define MAX(a, b) ((a) > (b) ? (a) : (b))
49 #define NODESIZE MAX(L1_CACHE_BYTES, 128)
64 #define LONG_PER_U64 (64 / BITS_PER_LONG)
103 static int longcmp(
const unsigned long *
l1,
const unsigned long *
l2,
size_t n)
107 for (i = 0; i <
n; i++) {
116 static unsigned long *longcpy(
unsigned long *
dest,
const unsigned long *
src,
121 for (i = 0; i <
n; i++)
126 static unsigned long *longset(
unsigned long *
s,
unsigned long c,
size_t n)
130 for (i = 0; i <
n; i++)
135 static void dec_key(
struct btree_geo *geo,
unsigned long *
key)
140 for (i = geo->
keylen - 1; i >= 0; i--) {
148 static unsigned long *
bkey(
struct btree_geo *geo,
unsigned long *node,
int n)
150 return &node[n * geo->
keylen];
153 static void *bval(
struct btree_geo *geo,
unsigned long *node,
int n)
161 longcpy(
bkey(geo, node, n), key, geo->
keylen);
164 static void setval(
struct btree_geo *geo,
unsigned long *node,
int n,
170 static void clearpair(
struct btree_geo *geo,
unsigned long *node,
int n)
176 static inline void __btree_init(
struct btree_head *head)
210 unsigned long *node = head->
node;
215 for ( ; height > 1; height--)
216 node = bval(geo, node, 0);
218 longcpy(key,
bkey(geo, node, 0), geo->
keylen);
219 return bval(geo, node, 0);
223 static int keycmp(
struct btree_geo *geo,
unsigned long *node,
int pos,
226 return longcmp(
bkey(geo, node, pos), key, geo->
keylen);
229 static int keyzero(
struct btree_geo *geo,
unsigned long *key)
233 for (i = 0; i < geo->
keylen; i++)
244 unsigned long *node = head->
node;
249 for ( ; height > 1; height--) {
251 if (keycmp(geo, node, i, key) <= 0)
255 node = bval(geo, node, i);
264 if (keycmp(geo, node, i, key) == 0)
265 return bval(geo, node, i);
271 unsigned long *key,
void *val)
274 unsigned long *node = head->
node;
279 for ( ; height > 1; height--) {
281 if (keycmp(geo, node, i, key) <= 0)
285 node = bval(geo, node, i);
294 if (keycmp(geo, node, i, key) == 0) {
295 setval(geo, node, i, val);
311 unsigned long *__key)
314 unsigned long *
node, *oldnode;
315 unsigned long *retry_key =
NULL, key[geo->
keylen];
317 if (keyzero(geo, __key))
322 longcpy(key, __key, geo->
keylen);
327 for (height = head->
height ; height > 1; height--) {
329 if (keycmp(geo, node, i, key) <= 0)
334 node = bval(geo, node, i);
337 retry_key =
bkey(geo, oldnode, i);
343 for (i = 0; i < geo->
no_pairs; i++) {
344 if (keycmp(geo, node, i, key) <= 0) {
345 if (bval(geo, node, i)) {
346 longcpy(__key,
bkey(geo, node, i), geo->
keylen);
347 return bval(geo, node, i);
354 longcpy(key, retry_key, geo->
keylen);
362 static int getpos(
struct btree_geo *geo,
unsigned long *node,
367 for (i = 0; i < geo->
no_pairs; i++) {
368 if (keycmp(geo, node, i, key) <= 0)
374 static int getfill(
struct btree_geo *geo,
unsigned long *node,
int start)
378 for (i = start; i < geo->
no_pairs; i++)
379 if (!bval(geo, node, i))
388 unsigned long *key,
int level)
390 unsigned long *node = head->
node;
393 for (height = head->
height; height > level; height--) {
395 if (keycmp(geo, node, i, key) <= 0)
398 if ((i == geo->
no_pairs) || !bval(geo, node, i)) {
403 setkey(geo, node, i, key);
406 node = bval(geo, node, i);
418 node = btree_node_alloc(head, gfp);
422 fill = getfill(geo, head->
node, 0);
424 setval(geo, node, 0, head->
node);
440 fill = getfill(geo, node, 0);
442 head->
node = bval(geo, node, 0);
448 unsigned long *key,
void *val,
int level,
455 if (head->
height < level) {
456 err = btree_grow(head, geo, gfp);
462 node = find_level(head, geo, key, level);
463 pos = getpos(geo, node, key);
464 fill = getfill(geo, node, pos);
466 BUG_ON(pos < fill && keycmp(geo, node, pos, key) == 0);
472 new = btree_node_alloc(head, gfp);
475 err = btree_insert_level(head, geo,
476 bkey(geo, node, fill / 2 - 1),
477 new, level + 1, gfp);
482 for (i = 0; i < fill / 2; i++) {
484 setval(geo,
new, i, bval(geo, node, i));
485 setkey(geo, node, i,
bkey(geo, node, i + fill / 2));
486 setval(geo, node, i, bval(geo, node, i + fill / 2));
487 clearpair(geo, node, i + fill / 2);
490 setkey(geo, node, i,
bkey(geo, node, fill - 1));
491 setval(geo, node, i, bval(geo, node, fill - 1));
492 clearpair(geo, node, fill - 1);
499 for (i = fill; i >
pos; i--) {
501 setval(geo, node, i, bval(geo, node, i - 1));
503 setkey(geo, node, pos, key);
504 setval(geo, node, pos, val);
510 unsigned long *key,
void *val,
gfp_t gfp)
513 return btree_insert_level(head, geo, key, val, 1, gfp);
518 unsigned long *key,
int level);
520 unsigned long *
left,
int lfill,
521 unsigned long *
right,
int rfill,
522 unsigned long *parent,
int lpos)
526 for (i = 0; i < rfill; i++) {
528 setkey(geo, left, lfill + i,
bkey(geo, right, i));
529 setval(geo, left, lfill + i, bval(geo, right, i));
532 setval(geo, parent, lpos, right);
533 setval(geo, parent, lpos + 1, left);
535 btree_remove_level(head, geo,
bkey(geo, parent, lpos), level + 1);
540 unsigned long *key,
int level,
unsigned long *
child,
int fill)
542 unsigned long *parent, *left =
NULL, *right =
NULL;
543 int i, no_left, no_right;
550 btree_remove_level(head, geo, key, level + 1);
555 parent = find_level(head, geo, key, level + 1);
556 i = getpos(geo, parent, key);
557 BUG_ON(bval(geo, parent, i) != child);
560 left = bval(geo, parent, i - 1);
561 no_left = getfill(geo, left, 0);
562 if (fill + no_left <= geo->no_pairs) {
563 merge(head, geo, level,
570 if (i + 1 < getfill(geo, parent, i)) {
571 right = bval(geo, parent, i + 1);
572 no_right = getfill(geo, right, 0);
573 if (fill + no_right <= geo->no_pairs) {
574 merge(head, geo, level,
591 unsigned long *key,
int level)
597 if (level > head->
height) {
604 node = find_level(head, geo, key, level);
605 pos = getpos(geo, node, key);
606 fill = getfill(geo, node, pos);
607 if ((level == 1) && (keycmp(geo, node, pos, key) != 0))
609 ret = bval(geo, node, pos);
612 for (i = pos; i < fill - 1; i++) {
614 setval(geo, node, i, bval(geo, node, i + 1));
616 clearpair(geo, node, fill - 1);
619 if (level < head->height)
620 rebalance(head, geo, key, level, node, fill - 1);
621 else if (fill - 1 == 1)
622 btree_shrink(head, geo);
634 return btree_remove_level(head, geo, key, 1);
641 unsigned long key[geo->
keylen];
642 unsigned long dup[geo->
keylen];
648 if (!(target->
node)) {
652 __btree_init(victim);
668 longcpy(dup, key, geo->
keylen);
676 unsigned long *node,
unsigned long opaque,
677 void (*
func)(
void *
elem,
unsigned long opaque,
678 unsigned long *key,
size_t index,
680 void *func2,
int reap,
int height,
size_t count)
683 unsigned long *child;
685 for (i = 0; i < geo->
no_pairs; i++) {
686 child = bval(geo, node, i);
690 count = __btree_for_each(head, geo, child, opaque,
691 func, func2, reap, height - 1, count);
693 func(child, opaque,
bkey(geo, node, i), count++,
701 static void empty(
void *elem,
unsigned long opaque,
unsigned long *key,
702 size_t index,
void *func2)
706 void visitorl(
void *elem,
unsigned long opaque,
unsigned long *key,
707 size_t index,
void *__func)
709 visitorl_t
func = __func;
711 func(elem, opaque, *key, index);
715 void visitor32(
void *elem,
unsigned long opaque,
unsigned long *__key,
716 size_t index,
void *__func)
718 visitor32_t
func = __func;
719 u32 *key = (
void *)__key;
721 func(elem, opaque, *key, index);
725 void visitor64(
void *elem,
unsigned long opaque,
unsigned long *__key,
726 size_t index,
void *__func)
728 visitor64_t
func = __func;
729 u64 *key = (
void *)__key;
731 func(elem, opaque, *key, index);
735 void visitor128(
void *elem,
unsigned long opaque,
unsigned long *__key,
736 size_t index,
void *__func)
739 u64 *key = (
void *)__key;
741 func(elem, opaque, key[0], key[1], index);
746 unsigned long opaque,
747 void (*
func)(
void *elem,
unsigned long opaque,
749 size_t index,
void *func2),
757 count = __btree_for_each(head, geo, head->
node, opaque,
func,
758 func2, 0, head->
height, 0);
764 unsigned long opaque,
765 void (*
func)(
void *elem,
unsigned long opaque,
767 size_t index,
void *func2),
775 count = __btree_for_each(head, geo, head->
node, opaque,
func,
776 func2, 1, head->
height, 0);
782 static int __init btree_module_init(
void)
789 static void __exit btree_module_exit(
void)