1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef BTREE_H 3*4882a593Smuzhiyun #define BTREE_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/kernel.h> 6*4882a593Smuzhiyun #include <linux/mempool.h> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun /** 9*4882a593Smuzhiyun * DOC: B+Tree basics 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * A B+Tree is a data structure for looking up arbitrary (currently allowing 12*4882a593Smuzhiyun * unsigned long, u32, u64 and 2 * u64) keys into pointers. The data structure 13*4882a593Smuzhiyun * is described at https://en.wikipedia.org/wiki/B-tree, we currently do not 14*4882a593Smuzhiyun * use binary search to find the key on lookups. 15*4882a593Smuzhiyun * 16*4882a593Smuzhiyun * Each B+Tree consists of a head, that contains bookkeeping information and 17*4882a593Smuzhiyun * a variable number (starting with zero) nodes. Each node contains the keys 18*4882a593Smuzhiyun * and pointers to sub-nodes, or, for leaf nodes, the keys and values for the 19*4882a593Smuzhiyun * tree entries. 20*4882a593Smuzhiyun * 21*4882a593Smuzhiyun * Each node in this implementation has the following layout: 22*4882a593Smuzhiyun * [key1, key2, ..., keyN] [val1, val2, ..., valN] 23*4882a593Smuzhiyun * 24*4882a593Smuzhiyun * Each key here is an array of unsigned longs, geo->no_longs in total. The 25*4882a593Smuzhiyun * number of keys and values (N) is geo->no_pairs. 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun /** 29*4882a593Smuzhiyun * struct btree_head - btree head 30*4882a593Smuzhiyun * 31*4882a593Smuzhiyun * @node: the first node in the tree 32*4882a593Smuzhiyun * @mempool: mempool used for node allocations 33*4882a593Smuzhiyun * @height: current of the tree 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun struct btree_head { 36*4882a593Smuzhiyun unsigned long *node; 37*4882a593Smuzhiyun mempool_t *mempool; 38*4882a593Smuzhiyun int height; 39*4882a593Smuzhiyun }; 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* btree geometry */ 42*4882a593Smuzhiyun struct btree_geo; 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun /** 45*4882a593Smuzhiyun * btree_alloc - allocate function for the mempool 46*4882a593Smuzhiyun * @gfp_mask: gfp mask for the allocation 47*4882a593Smuzhiyun * @pool_data: unused 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun void *btree_alloc(gfp_t gfp_mask, void *pool_data); 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun /** 52*4882a593Smuzhiyun * btree_free - free function for the mempool 53*4882a593Smuzhiyun * @element: the element to free 54*4882a593Smuzhiyun * @pool_data: unused 55*4882a593Smuzhiyun */ 56*4882a593Smuzhiyun void btree_free(void *element, void *pool_data); 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /** 59*4882a593Smuzhiyun * btree_init_mempool - initialise a btree with given mempool 60*4882a593Smuzhiyun * 61*4882a593Smuzhiyun * @head: the btree head to initialise 62*4882a593Smuzhiyun * @mempool: the mempool to use 63*4882a593Smuzhiyun * 64*4882a593Smuzhiyun * When this function is used, there is no need to destroy 65*4882a593Smuzhiyun * the mempool. 66*4882a593Smuzhiyun */ 67*4882a593Smuzhiyun void btree_init_mempool(struct btree_head *head, mempool_t *mempool); 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun /** 70*4882a593Smuzhiyun * btree_init - initialise a btree 71*4882a593Smuzhiyun * 72*4882a593Smuzhiyun * @head: the btree head to initialise 73*4882a593Smuzhiyun * 74*4882a593Smuzhiyun * This function allocates the memory pool that the 75*4882a593Smuzhiyun * btree needs. Returns zero or a negative error code 76*4882a593Smuzhiyun * (-%ENOMEM) when memory allocation fails. 77*4882a593Smuzhiyun * 78*4882a593Smuzhiyun */ 79*4882a593Smuzhiyun int __must_check btree_init(struct btree_head *head); 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /** 82*4882a593Smuzhiyun * btree_destroy - destroy mempool 83*4882a593Smuzhiyun * 84*4882a593Smuzhiyun * @head: the btree head to destroy 85*4882a593Smuzhiyun * 86*4882a593Smuzhiyun * This function destroys the internal memory pool, use only 87*4882a593Smuzhiyun * when using btree_init(), not with btree_init_mempool(). 88*4882a593Smuzhiyun */ 89*4882a593Smuzhiyun void btree_destroy(struct btree_head *head); 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /** 92*4882a593Smuzhiyun * btree_lookup - look up a key in the btree 93*4882a593Smuzhiyun * 94*4882a593Smuzhiyun * @head: the btree to look in 95*4882a593Smuzhiyun * @geo: the btree geometry 96*4882a593Smuzhiyun * @key: the key to look up 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * This function returns the value for the given key, or %NULL. 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun void *btree_lookup(struct btree_head *head, struct btree_geo *geo, 101*4882a593Smuzhiyun unsigned long *key); 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /** 104*4882a593Smuzhiyun * btree_insert - insert an entry into the btree 105*4882a593Smuzhiyun * 106*4882a593Smuzhiyun * @head: the btree to add to 107*4882a593Smuzhiyun * @geo: the btree geometry 108*4882a593Smuzhiyun * @key: the key to add (must not already be present) 109*4882a593Smuzhiyun * @val: the value to add (must not be %NULL) 110*4882a593Smuzhiyun * @gfp: allocation flags for node allocations 111*4882a593Smuzhiyun * 112*4882a593Smuzhiyun * This function returns 0 if the item could be added, or an 113*4882a593Smuzhiyun * error code if it failed (may fail due to memory pressure). 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun int __must_check btree_insert(struct btree_head *head, struct btree_geo *geo, 116*4882a593Smuzhiyun unsigned long *key, void *val, gfp_t gfp); 117*4882a593Smuzhiyun /** 118*4882a593Smuzhiyun * btree_update - update an entry in the btree 119*4882a593Smuzhiyun * 120*4882a593Smuzhiyun * @head: the btree to update 121*4882a593Smuzhiyun * @geo: the btree geometry 122*4882a593Smuzhiyun * @key: the key to update 123*4882a593Smuzhiyun * @val: the value to change it to (must not be %NULL) 124*4882a593Smuzhiyun * 125*4882a593Smuzhiyun * This function returns 0 if the update was successful, or 126*4882a593Smuzhiyun * -%ENOENT if the key could not be found. 127*4882a593Smuzhiyun */ 128*4882a593Smuzhiyun int btree_update(struct btree_head *head, struct btree_geo *geo, 129*4882a593Smuzhiyun unsigned long *key, void *val); 130*4882a593Smuzhiyun /** 131*4882a593Smuzhiyun * btree_remove - remove an entry from the btree 132*4882a593Smuzhiyun * 133*4882a593Smuzhiyun * @head: the btree to update 134*4882a593Smuzhiyun * @geo: the btree geometry 135*4882a593Smuzhiyun * @key: the key to remove 136*4882a593Smuzhiyun * 137*4882a593Smuzhiyun * This function returns the removed entry, or %NULL if the key 138*4882a593Smuzhiyun * could not be found. 139*4882a593Smuzhiyun */ 140*4882a593Smuzhiyun void *btree_remove(struct btree_head *head, struct btree_geo *geo, 141*4882a593Smuzhiyun unsigned long *key); 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /** 144*4882a593Smuzhiyun * btree_merge - merge two btrees 145*4882a593Smuzhiyun * 146*4882a593Smuzhiyun * @target: the tree that gets all the entries 147*4882a593Smuzhiyun * @victim: the tree that gets merged into @target 148*4882a593Smuzhiyun * @geo: the btree geometry 149*4882a593Smuzhiyun * @gfp: allocation flags 150*4882a593Smuzhiyun * 151*4882a593Smuzhiyun * The two trees @target and @victim may not contain the same keys, 152*4882a593Smuzhiyun * that is a bug and triggers a BUG(). This function returns zero 153*4882a593Smuzhiyun * if the trees were merged successfully, and may return a failure 154*4882a593Smuzhiyun * when memory allocation fails, in which case both trees might have 155*4882a593Smuzhiyun * been partially merged, i.e. some entries have been moved from 156*4882a593Smuzhiyun * @victim to @target. 157*4882a593Smuzhiyun */ 158*4882a593Smuzhiyun int btree_merge(struct btree_head *target, struct btree_head *victim, 159*4882a593Smuzhiyun struct btree_geo *geo, gfp_t gfp); 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /** 162*4882a593Smuzhiyun * btree_last - get last entry in btree 163*4882a593Smuzhiyun * 164*4882a593Smuzhiyun * @head: btree head 165*4882a593Smuzhiyun * @geo: btree geometry 166*4882a593Smuzhiyun * @key: last key 167*4882a593Smuzhiyun * 168*4882a593Smuzhiyun * Returns the last entry in the btree, and sets @key to the key 169*4882a593Smuzhiyun * of that entry; returns NULL if the tree is empty, in that case 170*4882a593Smuzhiyun * key is not changed. 171*4882a593Smuzhiyun */ 172*4882a593Smuzhiyun void *btree_last(struct btree_head *head, struct btree_geo *geo, 173*4882a593Smuzhiyun unsigned long *key); 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun /** 176*4882a593Smuzhiyun * btree_get_prev - get previous entry 177*4882a593Smuzhiyun * 178*4882a593Smuzhiyun * @head: btree head 179*4882a593Smuzhiyun * @geo: btree geometry 180*4882a593Smuzhiyun * @key: pointer to key 181*4882a593Smuzhiyun * 182*4882a593Smuzhiyun * The function returns the next item right before the value pointed to by 183*4882a593Smuzhiyun * @key, and updates @key with its key, or returns %NULL when there is no 184*4882a593Smuzhiyun * entry with a key smaller than the given key. 185*4882a593Smuzhiyun */ 186*4882a593Smuzhiyun void *btree_get_prev(struct btree_head *head, struct btree_geo *geo, 187*4882a593Smuzhiyun unsigned long *key); 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun /* internal use, use btree_visitor{l,32,64,128} */ 191*4882a593Smuzhiyun size_t btree_visitor(struct btree_head *head, struct btree_geo *geo, 192*4882a593Smuzhiyun unsigned long opaque, 193*4882a593Smuzhiyun void (*func)(void *elem, unsigned long opaque, 194*4882a593Smuzhiyun unsigned long *key, size_t index, 195*4882a593Smuzhiyun void *func2), 196*4882a593Smuzhiyun void *func2); 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun /* internal use, use btree_grim_visitor{l,32,64,128} */ 199*4882a593Smuzhiyun size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo, 200*4882a593Smuzhiyun unsigned long opaque, 201*4882a593Smuzhiyun void (*func)(void *elem, unsigned long opaque, 202*4882a593Smuzhiyun unsigned long *key, 203*4882a593Smuzhiyun size_t index, void *func2), 204*4882a593Smuzhiyun void *func2); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun #include <linux/btree-128.h> 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun extern struct btree_geo btree_geo32; 210*4882a593Smuzhiyun #define BTREE_TYPE_SUFFIX l 211*4882a593Smuzhiyun #define BTREE_TYPE_BITS BITS_PER_LONG 212*4882a593Smuzhiyun #define BTREE_TYPE_GEO &btree_geo32 213*4882a593Smuzhiyun #define BTREE_KEYTYPE unsigned long 214*4882a593Smuzhiyun #include <linux/btree-type.h> 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun #define btree_for_each_safel(head, key, val) \ 217*4882a593Smuzhiyun for (val = btree_lastl(head, &key); \ 218*4882a593Smuzhiyun val; \ 219*4882a593Smuzhiyun val = btree_get_prevl(head, &key)) 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun #define BTREE_TYPE_SUFFIX 32 222*4882a593Smuzhiyun #define BTREE_TYPE_BITS 32 223*4882a593Smuzhiyun #define BTREE_TYPE_GEO &btree_geo32 224*4882a593Smuzhiyun #define BTREE_KEYTYPE u32 225*4882a593Smuzhiyun #include <linux/btree-type.h> 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun #define btree_for_each_safe32(head, key, val) \ 228*4882a593Smuzhiyun for (val = btree_last32(head, &key); \ 229*4882a593Smuzhiyun val; \ 230*4882a593Smuzhiyun val = btree_get_prev32(head, &key)) 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun extern struct btree_geo btree_geo64; 233*4882a593Smuzhiyun #define BTREE_TYPE_SUFFIX 64 234*4882a593Smuzhiyun #define BTREE_TYPE_BITS 64 235*4882a593Smuzhiyun #define BTREE_TYPE_GEO &btree_geo64 236*4882a593Smuzhiyun #define BTREE_KEYTYPE u64 237*4882a593Smuzhiyun #include <linux/btree-type.h> 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun #define btree_for_each_safe64(head, key, val) \ 240*4882a593Smuzhiyun for (val = btree_last64(head, &key); \ 241*4882a593Smuzhiyun val; \ 242*4882a593Smuzhiyun val = btree_get_prev64(head, &key)) 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun #endif 245