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)
75 if (e1->start == e2->start) {
76 if (e1->end < e2->end)
78 else if (e1->end > e2->end)
83 if (e1->start < e2->start)
91 static inline int extent_equal(struct interval_node_extent *e1,
92 struct interval_node_extent *e2)
94 return (e1->start == e2->start) && (e1->end == e2->end);
97 static inline int extent_overlapped(struct interval_node_extent *e1,
98 struct interval_node_extent *e2)
100 return (e1->start <= e2->end) && (e2->start <= e1->end);
103 static inline int node_compare(struct interval_node *n1,
104 struct interval_node *n2)
106 return extent_compare(&n1->in_extent, &n2->in_extent);
109 int node_equal(struct interval_node *n1, struct interval_node *n2)
111 return extent_equal(&n1->in_extent, &n2->in_extent);
114 static inline __u64 max_u64(__u64 x, __u64 y)
116 return x > y ? x : y;
119 static inline __u64 min_u64(__u64 x, __u64 y)
121 return x < y ? x : y;
124 #define interval_for_each(node, root) \
125 for (node = interval_first(root); node != NULL; \
126 node = interval_next(node))
128 #define interval_for_each_reverse(node, root) \
129 for (node = interval_last(root); node != NULL; \
130 node = interval_prev(node))
132 static struct interval_node *interval_first(struct interval_node *node)
138 while (node->in_left)
139 node = node->in_left;
143 static struct interval_node *interval_last(struct interval_node *node)
149 while (node->in_right)
150 node = node->in_right;
154 static struct interval_node *interval_next(struct interval_node *node)
161 RETURN(interval_first(node->in_right));
162 while (node->in_parent && node_is_right_child(node))
163 node = node->in_parent;
164 RETURN(node->in_parent);
167 static struct interval_node *interval_prev(struct interval_node *node)
175 RETURN(interval_last(node->in_left));
177 while (node->in_parent && node_is_left_child(node))
178 node = node->in_parent;
180 RETURN(node->in_parent);
183 enum interval_iter interval_iterate(struct interval_node *root,
184 interval_callback_t func,
187 struct interval_node *node;
188 enum interval_iter rc = INTERVAL_ITER_CONT;
192 interval_for_each(node, root) {
193 rc = func(node, data);
194 if (rc == INTERVAL_ITER_STOP)
200 EXPORT_SYMBOL(interval_iterate);
202 enum interval_iter interval_iterate_reverse(struct interval_node *root,
203 interval_callback_t func,
206 struct interval_node *node;
207 enum interval_iter rc = INTERVAL_ITER_CONT;
211 interval_for_each_reverse(node, root) {
212 rc = func(node, data);
213 if (rc == INTERVAL_ITER_STOP)
219 EXPORT_SYMBOL(interval_iterate_reverse);
221 /* try to find a node with same interval in the tree,
222 * if found, return the pointer to the node, otherwise return NULL
224 struct interval_node *interval_find(struct interval_node *root,
225 struct interval_node_extent *ex)
227 struct interval_node *walk = root;
233 rc = extent_compare(ex, &walk->in_extent);
237 walk = walk->in_left;
239 walk = walk->in_right;
244 EXPORT_SYMBOL(interval_find);
246 static void __rotate_change_maxhigh(struct interval_node *node,
247 struct interval_node *rotate)
249 __u64 left_max, right_max;
251 rotate->in_max_high = node->in_max_high;
252 left_max = node->in_left ? node->in_left->in_max_high : 0;
253 right_max = node->in_right ? node->in_right->in_max_high : 0;
254 node->in_max_high = max_u64(interval_high(node),
255 max_u64(left_max, right_max));
258 /* The left rotation "pivots" around the link from node to node->right, and
259 * - node will be linked to node->right's left child, and
260 * - node->right's left child will be linked to node's right child.
262 static void __rotate_left(struct interval_node *node,
263 struct interval_node **root)
265 struct interval_node *right = node->in_right;
266 struct interval_node *parent = node->in_parent;
268 node->in_right = right->in_left;
270 right->in_left->in_parent = node;
272 right->in_left = node;
273 right->in_parent = parent;
275 if (node_is_left_child(node))
276 parent->in_left = right;
278 parent->in_right = right;
282 node->in_parent = right;
284 /* update max_high for node and right */
285 __rotate_change_maxhigh(node, right);
288 /* The right rotation "pivots" around the link from node to node->left, and
289 * - node will be linked to node->left's right child, and
290 * - node->left's right child will be linked to node's left child.
292 static void __rotate_right(struct interval_node *node,
293 struct interval_node **root)
295 struct interval_node *left = node->in_left;
296 struct interval_node *parent = node->in_parent;
298 node->in_left = left->in_right;
300 left->in_right->in_parent = node;
301 left->in_right = node;
303 left->in_parent = parent;
305 if (node_is_right_child(node))
306 parent->in_right = left;
308 parent->in_left = left;
312 node->in_parent = left;
314 /* update max_high for node and left */
315 __rotate_change_maxhigh(node, left);
318 #define interval_swap(a, b) do { \
319 struct interval_node *c = a; a = b; b = c; \
323 * Operations INSERT and DELETE, when run on a tree with n keys,
324 * take O(logN) time.Because they modify the tree, the result
325 * may violate the red-black properties.To restore these properties,
326 * we must change the colors of some of the nodes in the tree
327 * and also change the pointer structure.
329 static void interval_insert_color(struct interval_node *node,
330 struct interval_node **root)
332 struct interval_node *parent, *gparent;
336 while ((parent = node->in_parent) && node_is_red(parent)) {
337 gparent = parent->in_parent;
338 /* Parent is RED, so gparent must not be NULL */
339 if (node_is_left_child(parent)) {
340 struct interval_node *uncle;
342 uncle = gparent->in_right;
343 if (uncle && node_is_red(uncle)) {
344 uncle->in_color = INTERVAL_BLACK;
345 parent->in_color = INTERVAL_BLACK;
346 gparent->in_color = INTERVAL_RED;
351 if (parent->in_right == node) {
352 __rotate_left(parent, root);
353 interval_swap(node, parent);
356 parent->in_color = INTERVAL_BLACK;
357 gparent->in_color = INTERVAL_RED;
358 __rotate_right(gparent, root);
360 struct interval_node *uncle;
362 uncle = gparent->in_left;
363 if (uncle && node_is_red(uncle)) {
364 uncle->in_color = INTERVAL_BLACK;
365 parent->in_color = INTERVAL_BLACK;
366 gparent->in_color = INTERVAL_RED;
371 if (node_is_left_child(node)) {
372 __rotate_right(parent, root);
373 interval_swap(node, parent);
376 parent->in_color = INTERVAL_BLACK;
377 gparent->in_color = INTERVAL_RED;
378 __rotate_left(gparent, root);
382 (*root)->in_color = INTERVAL_BLACK;
386 struct interval_node *interval_insert(struct interval_node *node,
387 struct interval_node **root)
389 struct interval_node **p, *parent = NULL;
393 LASSERT(!interval_is_intree(node));
397 if (node_equal(parent, node))
400 /* max_high field must be updated after each iteration */
401 if (parent->in_max_high < interval_high(node))
402 parent->in_max_high = interval_high(node);
404 if (node_compare(node, parent) < 0)
405 p = &parent->in_left;
407 p = &parent->in_right;
410 /* link node into the tree */
411 node->in_parent = parent;
412 node->in_color = INTERVAL_RED;
413 node->in_left = node->in_right = NULL;
416 interval_insert_color(node, root);
421 EXPORT_SYMBOL(interval_insert);
423 static inline int node_is_black_or_0(struct interval_node *node)
425 return !node || node_is_black(node);
428 static void interval_erase_color(struct interval_node *node,
429 struct interval_node *parent,
430 struct interval_node **root)
432 struct interval_node *tmp;
436 while (node_is_black_or_0(node) && node != *root) {
437 if (parent->in_left == node) {
438 tmp = parent->in_right;
439 if (node_is_red(tmp)) {
440 tmp->in_color = INTERVAL_BLACK;
441 parent->in_color = INTERVAL_RED;
442 __rotate_left(parent, root);
443 tmp = parent->in_right;
445 if (node_is_black_or_0(tmp->in_left) &&
446 node_is_black_or_0(tmp->in_right)) {
447 tmp->in_color = INTERVAL_RED;
449 parent = node->in_parent;
451 if (node_is_black_or_0(tmp->in_right)) {
452 struct interval_node *o_left;
454 if ((o_left = tmp->in_left))
457 tmp->in_color = INTERVAL_RED;
458 __rotate_right(tmp, root);
459 tmp = parent->in_right;
461 tmp->in_color = parent->in_color;
462 parent->in_color = INTERVAL_BLACK;
464 tmp->in_right->in_color =
466 __rotate_left(parent, root);
471 tmp = parent->in_left;
472 if (node_is_red(tmp)) {
473 tmp->in_color = INTERVAL_BLACK;
474 parent->in_color = INTERVAL_RED;
475 __rotate_right(parent, root);
476 tmp = parent->in_left;
478 if (node_is_black_or_0(tmp->in_left) &&
479 node_is_black_or_0(tmp->in_right)) {
480 tmp->in_color = INTERVAL_RED;
482 parent = node->in_parent;
484 if (node_is_black_or_0(tmp->in_left)) {
485 struct interval_node *o_right;
487 if ((o_right = tmp->in_right))
490 tmp->in_color = INTERVAL_RED;
491 __rotate_left(tmp, root);
492 tmp = parent->in_left;
494 tmp->in_color = parent->in_color;
495 parent->in_color = INTERVAL_BLACK;
497 tmp->in_left->in_color = INTERVAL_BLACK;
498 __rotate_right(parent, root);
505 node->in_color = INTERVAL_BLACK;
510 * if the @max_high value of @node is changed, this function traverse a path
511 * from node up to the root to update max_high for the whole tree.
513 static void update_maxhigh(struct interval_node *node,
516 __u64 left_max, right_max;
521 left_max = node->in_left ? node->in_left->in_max_high : 0;
522 right_max = node->in_right ? node->in_right->in_max_high : 0;
523 node->in_max_high = max_u64(interval_high(node),
524 max_u64(left_max, right_max));
526 if (node->in_max_high >= old_maxhigh)
528 node = node->in_parent;
533 void interval_erase(struct interval_node *node,
534 struct interval_node **root)
536 struct interval_node *child, *parent;
541 LASSERT(interval_is_intree(node));
543 if (!node->in_left) {
544 child = node->in_right;
545 } else if (!node->in_right) {
546 child = node->in_left;
547 } else { /* Both left and right child are not NULL */
548 struct interval_node *old = node;
550 node = interval_next(node);
551 child = node->in_right;
552 parent = node->in_parent;
553 color = node->in_color;
556 child->in_parent = parent;
558 parent->in_right = child;
560 parent->in_left = child;
562 node->in_color = old->in_color;
563 node->in_right = old->in_right;
564 node->in_left = old->in_left;
565 node->in_parent = old->in_parent;
567 if (old->in_parent) {
568 if (node_is_left_child(old))
569 old->in_parent->in_left = node;
571 old->in_parent->in_right = node;
576 old->in_left->in_parent = node;
578 old->in_right->in_parent = node;
579 update_maxhigh(child ? : parent, node->in_max_high);
580 update_maxhigh(node, old->in_max_high);
585 parent = node->in_parent;
586 color = node->in_color;
589 child->in_parent = parent;
591 if (node_is_left_child(node))
592 parent->in_left = child;
594 parent->in_right = child;
599 update_maxhigh(child ? : parent, node->in_max_high);
602 if (color == INTERVAL_BLACK)
603 interval_erase_color(child, parent, root);
606 EXPORT_SYMBOL(interval_erase);
608 static inline int interval_may_overlap(struct interval_node *node,
609 struct interval_node_extent *ext)
611 return (ext->start <= node->in_max_high &&
612 ext->end >= interval_low(node));
616 * This function finds all intervals that overlap interval ext,
617 * and calls func to handle resulted intervals one by one.
618 * in lustre, this function will find all conflicting locks in
619 * the granted queue and add these locks to the ast work list.
624 * if (ext->end < interval_low(node)) {
625 * interval_search(node->in_left, ext, func, data);
626 * } else if (interval_may_overlap(node, ext)) {
627 * if (extent_overlapped(ext, &node->in_extent))
629 * interval_search(node->in_left, ext, func, data);
630 * interval_search(node->in_right, ext, func, data);
636 enum interval_iter interval_search(struct interval_node *node,
637 struct interval_node_extent *ext,
638 interval_callback_t func,
641 struct interval_node *parent;
642 enum interval_iter rc = INTERVAL_ITER_CONT;
646 LASSERT(ext != NULL);
647 LASSERT(func != NULL);
650 if (ext->end < interval_low(node)) {
652 node = node->in_left;
655 } else if (interval_may_overlap(node, ext)) {
656 if (extent_overlapped(ext, &node->in_extent)) {
657 rc = func(node, data);
658 if (rc == INTERVAL_ITER_STOP)
663 node = node->in_left;
666 if (node->in_right) {
667 node = node->in_right;
672 parent = node->in_parent;
674 if (node_is_left_child(node) &&
676 /* If we ever got the left, it means that the
677 * parent met ext->end<interval_low(parent), or
678 * may_overlap(parent). If the former is true,
679 * we needn't go back. So stop early and check
680 * may_overlap(parent) after this loop.
682 node = parent->in_right;
686 parent = parent->in_parent;
688 if (parent == NULL || !interval_may_overlap(parent, ext))
694 EXPORT_SYMBOL(interval_search);
696 static enum interval_iter interval_overlap_cb(struct interval_node *n,
700 return INTERVAL_ITER_STOP;
703 int interval_is_overlapped(struct interval_node *root,
704 struct interval_node_extent *ext)
707 (void)interval_search(root, ext, interval_overlap_cb, &has);
710 EXPORT_SYMBOL(interval_is_overlapped);
712 /* Don't expand to low. Expanding downwards is expensive, and meaningless to
713 * some extents, because programs seldom do IO backward.
715 * The recursive algorithm of expanding low:
717 * struct interval_node *tmp;
718 * static __u64 res = 0;
722 * if (root->in_max_high < low) {
723 * res = max_u64(root->in_max_high + 1, res);
725 * } else if (low < interval_low(root)) {
726 * interval_expand_low(root->in_left, low);
730 * if (interval_high(root) < low)
731 * res = max_u64(interval_high(root) + 1, res);
732 * interval_expand_low(root->in_left, low);
733 * interval_expand_low(root->in_right, low);
738 * It's much easy to eliminate the recursion, see interval_search for
741 static inline __u64 interval_expand_low(struct interval_node *root, __u64 low)
743 /* we only concern the empty tree right now. */
749 static inline __u64 interval_expand_high(struct interval_node *node, __u64 high)
753 while (node != NULL) {
754 if (node->in_max_high < high)
757 if (interval_low(node) > high) {
758 result = interval_low(node) - 1;
759 node = node->in_left;
761 node = node->in_right;
768 /* expanding the extent based on @ext. */
769 void interval_expand(struct interval_node *root,
770 struct interval_node_extent *ext,
771 struct interval_node_extent *limiter)
773 /* The assertion of interval_is_overlapped is expensive because we may
774 * travel many nodes to find the overlapped node.
776 LASSERT(interval_is_overlapped(root, ext) == 0);
777 if (!limiter || limiter->start < ext->start)
778 ext->start = interval_expand_low(root, ext->start);
779 if (!limiter || limiter->end > ext->end)
780 ext->end = interval_expand_high(root, ext->end);
781 LASSERT(interval_is_overlapped(root, ext) == 0);