4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2014, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/ldlm/interval_tree.c
34 * Interval tree library used by ldlm extent lock code
36 * Author: Huang Wei <huangwei@clusterfs.com>
37 * Author: Jay Xiong <jinshan.xiong@sun.com>
40 #include <lustre_dlm.h>
41 #include <interval_tree.h>
48 static inline int node_is_left_child(struct interval_node *node)
50 LASSERT(node->in_parent != NULL);
51 return node == node->in_parent->in_left;
54 static inline int node_is_right_child(struct interval_node *node)
56 LASSERT(node->in_parent != NULL);
57 return node == node->in_parent->in_right;
60 static inline int node_is_red(struct interval_node *node)
62 return node->in_color == INTERVAL_RED;
65 static inline int node_is_black(struct interval_node *node)
67 return node->in_color == INTERVAL_BLACK;
70 static inline int extent_compare(struct interval_node_extent *e1,
71 struct interval_node_extent *e2)
74 if (e1->start == e2->start) {
75 if (e1->end < e2->end)
77 else if (e1->end > e2->end)
82 if (e1->start < e2->start)
90 static inline int extent_equal(struct interval_node_extent *e1,
91 struct interval_node_extent *e2)
93 return (e1->start == e2->start) && (e1->end == e2->end);
96 static inline int extent_overlapped(struct interval_node_extent *e1,
97 struct interval_node_extent *e2)
99 return (e1->start <= e2->end) && (e2->start <= e1->end);
102 static inline int node_compare(struct interval_node *n1,
103 struct interval_node *n2)
105 return extent_compare(&n1->in_extent, &n2->in_extent);
108 int node_equal(struct interval_node *n1, struct interval_node *n2)
110 return extent_equal(&n1->in_extent, &n2->in_extent);
113 static inline __u64 max_u64(__u64 x, __u64 y)
115 return x > y ? x : y;
118 static inline __u64 min_u64(__u64 x, __u64 y)
120 return x < y ? x : y;
123 #define interval_for_each(node, root) \
124 for (node = interval_first(root); node != NULL; \
125 node = interval_next(node))
127 #define interval_for_each_reverse(node, root) \
128 for (node = interval_last(root); node != NULL; \
129 node = interval_prev(node))
131 static struct interval_node *interval_first(struct interval_node *node)
137 while (node->in_left)
138 node = node->in_left;
142 static struct interval_node *interval_last(struct interval_node *node)
148 while (node->in_right)
149 node = node->in_right;
153 static struct interval_node *interval_next(struct interval_node *node)
160 RETURN(interval_first(node->in_right));
161 while (node->in_parent && node_is_right_child(node))
162 node = node->in_parent;
163 RETURN(node->in_parent);
166 static struct interval_node *interval_prev(struct interval_node *node)
174 RETURN(interval_last(node->in_left));
176 while (node->in_parent && node_is_left_child(node))
177 node = node->in_parent;
179 RETURN(node->in_parent);
182 enum interval_iter interval_iterate(struct interval_node *root,
183 interval_callback_t func,
186 struct interval_node *node;
187 enum interval_iter rc = INTERVAL_ITER_CONT;
190 interval_for_each(node, root) {
191 rc = func(node, data);
192 if (rc == INTERVAL_ITER_STOP)
198 EXPORT_SYMBOL(interval_iterate);
200 enum interval_iter interval_iterate_reverse(struct interval_node *root,
201 interval_callback_t func,
204 struct interval_node *node;
205 enum interval_iter rc = INTERVAL_ITER_CONT;
208 interval_for_each_reverse(node, root) {
209 rc = func(node, data);
210 if (rc == INTERVAL_ITER_STOP)
216 EXPORT_SYMBOL(interval_iterate_reverse);
218 /* try to find a node with same interval in the tree,
219 * if found, return the pointer to the node, otherwise return NULL*/
220 struct interval_node *interval_find(struct interval_node *root,
221 struct interval_node_extent *ex)
223 struct interval_node *walk = root;
228 rc = extent_compare(ex, &walk->in_extent);
232 walk = walk->in_left;
234 walk = walk->in_right;
239 EXPORT_SYMBOL(interval_find);
241 static void __rotate_change_maxhigh(struct interval_node *node,
242 struct interval_node *rotate)
244 __u64 left_max, right_max;
246 rotate->in_max_high = node->in_max_high;
247 left_max = node->in_left ? node->in_left->in_max_high : 0;
248 right_max = node->in_right ? node->in_right->in_max_high : 0;
249 node->in_max_high = max_u64(interval_high(node),
250 max_u64(left_max,right_max));
253 /* The left rotation "pivots" around the link from node to node->right, and
254 * - node will be linked to node->right's left child, and
255 * - node->right's left child will be linked to node's right child. */
256 static void __rotate_left(struct interval_node *node,
257 struct interval_node **root)
259 struct interval_node *right = node->in_right;
260 struct interval_node *parent = node->in_parent;
262 node->in_right = right->in_left;
264 right->in_left->in_parent = node;
266 right->in_left = node;
267 right->in_parent = parent;
269 if (node_is_left_child(node))
270 parent->in_left = right;
272 parent->in_right = right;
276 node->in_parent = right;
278 /* update max_high for node and right */
279 __rotate_change_maxhigh(node, right);
282 /* The right rotation "pivots" around the link from node to node->left, and
283 * - node will be linked to node->left's right child, and
284 * - node->left's right child will be linked to node's left child. */
285 static void __rotate_right(struct interval_node *node,
286 struct interval_node **root)
288 struct interval_node *left = node->in_left;
289 struct interval_node *parent = node->in_parent;
291 node->in_left = left->in_right;
293 left->in_right->in_parent = node;
294 left->in_right = node;
296 left->in_parent = parent;
298 if (node_is_right_child(node))
299 parent->in_right = left;
301 parent->in_left = left;
305 node->in_parent = left;
307 /* update max_high for node and left */
308 __rotate_change_maxhigh(node, left);
311 #define interval_swap(a, b) do { \
312 struct interval_node *c = a; a = b; b = c; \
316 * Operations INSERT and DELETE, when run on a tree with n keys,
317 * take O(logN) time.Because they modify the tree, the result
318 * may violate the red-black properties.To restore these properties,
319 * we must change the colors of some of the nodes in the tree
320 * and also change the pointer structure.
322 static void interval_insert_color(struct interval_node *node,
323 struct interval_node **root)
325 struct interval_node *parent, *gparent;
328 while ((parent = node->in_parent) && node_is_red(parent)) {
329 gparent = parent->in_parent;
330 /* Parent is RED, so gparent must not be NULL */
331 if (node_is_left_child(parent)) {
332 struct interval_node *uncle;
333 uncle = gparent->in_right;
334 if (uncle && node_is_red(uncle)) {
335 uncle->in_color = INTERVAL_BLACK;
336 parent->in_color = INTERVAL_BLACK;
337 gparent->in_color = INTERVAL_RED;
342 if (parent->in_right == node) {
343 __rotate_left(parent, root);
344 interval_swap(node, parent);
347 parent->in_color = INTERVAL_BLACK;
348 gparent->in_color = INTERVAL_RED;
349 __rotate_right(gparent, root);
351 struct interval_node *uncle;
352 uncle = gparent->in_left;
353 if (uncle && node_is_red(uncle)) {
354 uncle->in_color = INTERVAL_BLACK;
355 parent->in_color = INTERVAL_BLACK;
356 gparent->in_color = INTERVAL_RED;
361 if (node_is_left_child(node)) {
362 __rotate_right(parent, root);
363 interval_swap(node, parent);
366 parent->in_color = INTERVAL_BLACK;
367 gparent->in_color = INTERVAL_RED;
368 __rotate_left(gparent, root);
372 (*root)->in_color = INTERVAL_BLACK;
376 struct interval_node *interval_insert(struct interval_node *node,
377 struct interval_node **root)
380 struct interval_node **p, *parent = NULL;
383 LASSERT(!interval_is_intree(node));
387 if (node_equal(parent, node))
390 /* max_high field must be updated after each iteration */
391 if (parent->in_max_high < interval_high(node))
392 parent->in_max_high = interval_high(node);
394 if (node_compare(node, parent) < 0)
395 p = &parent->in_left;
397 p = &parent->in_right;
400 /* link node into the tree */
401 node->in_parent = parent;
402 node->in_color = INTERVAL_RED;
403 node->in_left = node->in_right = NULL;
406 interval_insert_color(node, root);
411 EXPORT_SYMBOL(interval_insert);
413 static inline int node_is_black_or_0(struct interval_node *node)
415 return !node || node_is_black(node);
418 static void interval_erase_color(struct interval_node *node,
419 struct interval_node *parent,
420 struct interval_node **root)
422 struct interval_node *tmp;
425 while (node_is_black_or_0(node) && node != *root) {
426 if (parent->in_left == node) {
427 tmp = parent->in_right;
428 if (node_is_red(tmp)) {
429 tmp->in_color = INTERVAL_BLACK;
430 parent->in_color = INTERVAL_RED;
431 __rotate_left(parent, root);
432 tmp = parent->in_right;
434 if (node_is_black_or_0(tmp->in_left) &&
435 node_is_black_or_0(tmp->in_right)) {
436 tmp->in_color = INTERVAL_RED;
438 parent = node->in_parent;
440 if (node_is_black_or_0(tmp->in_right)) {
441 struct interval_node *o_left;
442 if ((o_left = tmp->in_left))
443 o_left->in_color = INTERVAL_BLACK;
444 tmp->in_color = INTERVAL_RED;
445 __rotate_right(tmp, root);
446 tmp = parent->in_right;
448 tmp->in_color = parent->in_color;
449 parent->in_color = INTERVAL_BLACK;
451 tmp->in_right->in_color = INTERVAL_BLACK;
452 __rotate_left(parent, root);
457 tmp = parent->in_left;
458 if (node_is_red(tmp)) {
459 tmp->in_color = INTERVAL_BLACK;
460 parent->in_color = INTERVAL_RED;
461 __rotate_right(parent, root);
462 tmp = parent->in_left;
464 if (node_is_black_or_0(tmp->in_left) &&
465 node_is_black_or_0(tmp->in_right)) {
466 tmp->in_color = INTERVAL_RED;
468 parent = node->in_parent;
470 if (node_is_black_or_0(tmp->in_left)) {
471 struct interval_node *o_right;
472 if ((o_right = tmp->in_right))
473 o_right->in_color = INTERVAL_BLACK;
474 tmp->in_color = INTERVAL_RED;
475 __rotate_left(tmp, root);
476 tmp = parent->in_left;
478 tmp->in_color = parent->in_color;
479 parent->in_color = INTERVAL_BLACK;
481 tmp->in_left->in_color = INTERVAL_BLACK;
482 __rotate_right(parent, root);
489 node->in_color = INTERVAL_BLACK;
494 * if the @max_high value of @node is changed, this function traverse a path
495 * from node up to the root to update max_high for the whole tree.
497 static void update_maxhigh(struct interval_node *node,
500 __u64 left_max, right_max;
504 left_max = node->in_left ? node->in_left->in_max_high : 0;
505 right_max = node->in_right ? node->in_right->in_max_high : 0;
506 node->in_max_high = max_u64(interval_high(node),
507 max_u64(left_max, right_max));
509 if (node->in_max_high >= old_maxhigh)
511 node = node->in_parent;
516 void interval_erase(struct interval_node *node,
517 struct interval_node **root)
519 struct interval_node *child, *parent;
523 LASSERT(interval_is_intree(node));
525 if (!node->in_left) {
526 child = node->in_right;
527 } else if (!node->in_right) {
528 child = node->in_left;
529 } else { /* Both left and right child are not NULL */
530 struct interval_node *old = node;
532 node = interval_next(node);
533 child = node->in_right;
534 parent = node->in_parent;
535 color = node->in_color;
538 child->in_parent = parent;
540 parent->in_right = child;
542 parent->in_left = child;
544 node->in_color = old->in_color;
545 node->in_right = old->in_right;
546 node->in_left = old->in_left;
547 node->in_parent = old->in_parent;
549 if (old->in_parent) {
550 if (node_is_left_child(old))
551 old->in_parent->in_left = node;
553 old->in_parent->in_right = node;
558 old->in_left->in_parent = node;
560 old->in_right->in_parent = node;
561 update_maxhigh(child ? : parent, node->in_max_high);
562 update_maxhigh(node, old->in_max_high);
567 parent = node->in_parent;
568 color = node->in_color;
571 child->in_parent = parent;
573 if (node_is_left_child(node))
574 parent->in_left = child;
576 parent->in_right = child;
581 update_maxhigh(child ? : parent, node->in_max_high);
584 if (color == INTERVAL_BLACK)
585 interval_erase_color(child, parent, root);
588 EXPORT_SYMBOL(interval_erase);
590 static inline int interval_may_overlap(struct interval_node *node,
591 struct interval_node_extent *ext)
593 return (ext->start <= node->in_max_high &&
594 ext->end >= interval_low(node));
598 * This function finds all intervals that overlap interval ext,
599 * and calls func to handle resulted intervals one by one.
600 * in lustre, this function will find all conflicting locks in
601 * the granted queue and add these locks to the ast work list.
606 * if (ext->end < interval_low(node)) {
607 * interval_search(node->in_left, ext, func, data);
608 * } else if (interval_may_overlap(node, ext)) {
609 * if (extent_overlapped(ext, &node->in_extent))
611 * interval_search(node->in_left, ext, func, data);
612 * interval_search(node->in_right, ext, func, data);
618 enum interval_iter interval_search(struct interval_node *node,
619 struct interval_node_extent *ext,
620 interval_callback_t func,
623 struct interval_node *parent;
624 enum interval_iter rc = INTERVAL_ITER_CONT;
628 LASSERT(ext != NULL);
629 LASSERT(func != NULL);
632 if (ext->end < interval_low(node)) {
634 node = node->in_left;
637 } else if (interval_may_overlap(node, ext)) {
638 if (extent_overlapped(ext, &node->in_extent)) {
639 rc = func(node, data);
640 if (rc == INTERVAL_ITER_STOP)
645 node = node->in_left;
648 if (node->in_right) {
649 node = node->in_right;
654 parent = node->in_parent;
656 if (node_is_left_child(node) &&
658 /* If we ever got the left, it means that the
659 * parent met ext->end<interval_low(parent), or
660 * may_overlap(parent). If the former is true,
661 * we needn't go back. So stop early and check
662 * may_overlap(parent) after this loop. */
663 node = parent->in_right;
667 parent = parent->in_parent;
669 if (parent == NULL || !interval_may_overlap(parent, ext))
675 EXPORT_SYMBOL(interval_search);
677 static enum interval_iter interval_overlap_cb(struct interval_node *n,
681 return INTERVAL_ITER_STOP;
684 int interval_is_overlapped(struct interval_node *root,
685 struct interval_node_extent *ext)
688 (void)interval_search(root, ext, interval_overlap_cb, &has);
691 EXPORT_SYMBOL(interval_is_overlapped);
693 /* Don't expand to low. Expanding downwards is expensive, and meaningless to
694 * some extents, because programs seldom do IO backward.
696 * The recursive algorithm of expanding low:
698 * struct interval_node *tmp;
699 * static __u64 res = 0;
703 * if (root->in_max_high < low) {
704 * res = max_u64(root->in_max_high + 1, res);
706 * } else if (low < interval_low(root)) {
707 * interval_expand_low(root->in_left, low);
711 * if (interval_high(root) < low)
712 * res = max_u64(interval_high(root) + 1, res);
713 * interval_expand_low(root->in_left, low);
714 * interval_expand_low(root->in_right, low);
719 * It's much easy to eliminate the recursion, see interval_search for
722 static inline __u64 interval_expand_low(struct interval_node *root, __u64 low)
724 /* we only concern the empty tree right now. */
730 static inline __u64 interval_expand_high(struct interval_node *node, __u64 high)
734 while (node != NULL) {
735 if (node->in_max_high < high)
738 if (interval_low(node) > high) {
739 result = interval_low(node) - 1;
740 node = node->in_left;
742 node = node->in_right;
749 /* expanding the extent based on @ext. */
750 void interval_expand(struct interval_node *root,
751 struct interval_node_extent *ext,
752 struct interval_node_extent *limiter)
754 /* The assertion of interval_is_overlapped is expensive because we may
755 * travel many nodes to find the overlapped node. */
756 LASSERT(interval_is_overlapped(root, ext) == 0);
757 if (!limiter || limiter->start < ext->start)
758 ext->start = interval_expand_low(root, ext->start);
759 if (!limiter || limiter->end > ext->end)
760 ext->end = interval_expand_high(root, ext->end);
761 LASSERT(interval_is_overlapped(root, ext) == 0);