199
199
node_shift(right, count);
202
left->header.nr_entries =
203
cpu_to_le32(le32_to_cpu(left->header.nr_entries) - count);
204
BUG_ON(le32_to_cpu(left->header.nr_entries) > le32_to_cpu(left->header.max_entries));
206
right->header.nr_entries =
207
cpu_to_le32(le32_to_cpu(right->header.nr_entries) + count);
208
BUG_ON(le32_to_cpu(right->header.nr_entries) > le32_to_cpu(right->header.max_entries));
202
left->header.nr_entries = cpu_to_le32(nr_left - count);
203
right->header.nr_entries = cpu_to_le32(nr_right + count);
211
206
static void __rebalance2(struct dm_btree_info *info, struct node *parent,
272
265
return exit_child(info, &right);
269
* We dump as many entries from center as possible into left, then the rest
270
* in right, then rebalance2. This wastes some cpu, but I want something
273
static void delete_center_node(struct dm_btree_info *info, struct node *parent,
274
struct child *l, struct child *c, struct child *r,
275
struct node *left, struct node *center, struct node *right,
276
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
278
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
279
unsigned shift = min(max_entries - nr_left, nr_center);
281
BUG_ON(nr_left + shift > max_entries);
282
node_copy(left, center, -shift);
283
left->header.nr_entries = cpu_to_le32(nr_left + shift);
285
if (shift != nr_center) {
286
shift = nr_center - shift;
287
BUG_ON((nr_right + shift) > max_entries);
288
node_shift(right, shift);
289
node_copy(center, right, shift);
290
right->header.nr_entries = cpu_to_le32(nr_right + shift);
292
*key_ptr(parent, r->index) = right->keys[0];
294
delete_at(parent, c->index);
297
dm_tm_dec(info->tm, dm_block_location(c->block));
298
__rebalance2(info, parent, l, r);
302
* Redistributes entries among 3 sibling nodes.
304
static void redistribute3(struct dm_btree_info *info, struct node *parent,
305
struct child *l, struct child *c, struct child *r,
306
struct node *left, struct node *center, struct node *right,
307
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
310
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
311
unsigned target = (nr_left + nr_center + nr_right) / 3;
312
BUG_ON(target > max_entries);
314
if (nr_left < nr_right) {
315
s = nr_left - target;
317
if (s < 0 && nr_center < -s) {
318
/* not enough in central node */
319
shift(left, center, nr_center);
320
s = nr_center - target;
321
shift(left, right, s);
324
shift(left, center, s);
326
shift(center, right, target - nr_right);
329
s = target - nr_right;
330
if (s > 0 && nr_center < s) {
331
/* not enough in central node */
332
shift(center, right, nr_center);
333
s = target - nr_center;
334
shift(left, right, s);
337
shift(center, right, s);
339
shift(left, center, nr_left - target);
342
*key_ptr(parent, c->index) = center->keys[0];
343
*key_ptr(parent, r->index) = right->keys[0];
275
346
static void __rebalance3(struct dm_btree_info *info, struct node *parent,
276
347
struct child *l, struct child *c, struct child *r)
282
353
uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
283
354
uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
284
355
uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
285
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
357
unsigned threshold = merge_threshold(left) * 4 + 1;
289
359
BUG_ON(left->header.max_entries != center->header.max_entries);
290
360
BUG_ON(center->header.max_entries != right->header.max_entries);
292
if (((nr_left + nr_center + nr_right) / 2) < merge_threshold(center)) {
294
* Delete center node:
296
* We dump as many entries from center as possible into
297
* left, then the rest in right, then rebalance2. This
298
* wastes some cpu, but I want something simple atm.
300
unsigned shift = min(max_entries - nr_left, nr_center);
302
BUG_ON(nr_left + shift > max_entries);
303
node_copy(left, center, -shift);
304
left->header.nr_entries = cpu_to_le32(nr_left + shift);
306
if (shift != nr_center) {
307
shift = nr_center - shift;
308
BUG_ON((nr_right + shift) >= max_entries);
309
node_shift(right, shift);
310
node_copy(center, right, shift);
311
right->header.nr_entries = cpu_to_le32(nr_right + shift);
313
*key_ptr(parent, r->index) = right->keys[0];
315
delete_at(parent, c->index);
318
dm_tm_dec(info->tm, dm_block_location(c->block));
319
__rebalance2(info, parent, l, r);
327
target = (nr_left + nr_center + nr_right) / 3;
328
BUG_ON(target > max_entries);
331
* Adjust the left node
333
shift(left, center, nr_left - target);
336
* Adjust the right node
338
shift(center, right, target - nr_right);
339
*key_ptr(parent, c->index) = center->keys[0];
340
*key_ptr(parent, r->index) = right->keys[0];
362
if ((nr_left + nr_center + nr_right) < threshold)
363
delete_center_node(info, parent, l, c, r, left, center, right,
364
nr_left, nr_center, nr_right);
366
redistribute3(info, parent, l, c, r, left, center, right,
367
nr_left, nr_center, nr_right);
343
370
static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,