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.
27 * This file is part of Lustre, http://www.lustre.org/
28 * Lustre is a trademark of Sun Microsystems, Inc.
30 * lustre/ldlm/interval_tree.c
32 * Interval tree library used by ldlm extent lock code
34 * Author: Huang Wei <huangwei@clusterfs.com>
35 * Author: Jay Xiong <jinshan.xiong@sun.com>
37 #include <lustre_dlm.h>
38 #include <obd_support.h>
39 #include <interval_tree.h>
46 static inline int node_is_left_child(struct interval_node *node)
48 return node == node->in_parent->in_left;
51 static inline int node_is_right_child(struct interval_node *node)
53 return node == node->in_parent->in_right;
56 static inline int node_is_red(struct interval_node *node)
58 return node->in_color == INTERVAL_RED;
61 static inline int node_is_black(struct interval_node *node)
63 return node->in_color == INTERVAL_BLACK;
66 static inline int extent_compare(struct interval_node_extent *e1,
67 struct interval_node_extent *e2)
71 if (e1->start == e2->start) {
72 if (e1->end < e2->end)
74 else if (e1->end > e2->end)
79 if (e1->start < e2->start)
87 static inline int extent_equal(struct interval_node_extent *e1,
88 struct interval_node_extent *e2)
90 return (e1->start == e2->start) && (e1->end == e2->end);
93 static inline int extent_overlapped(struct interval_node_extent *e1,
94 struct interval_node_extent *e2)
96 return (e1->start <= e2->end) && (e2->start <= e1->end);
99 static inline int node_equal(struct interval_node *n1, struct interval_node *n2)
101 return extent_equal(&n1->in_extent, &n2->in_extent);
104 static struct interval_node *interval_first(struct interval_node *node)
108 while (node->in_left)
109 node = node->in_left;
113 static struct interval_node *interval_last(struct interval_node *node)
117 while (node->in_right)
118 node = node->in_right;
122 static struct interval_node *interval_next(struct interval_node *node)
127 return interval_first(node->in_right);
128 while (node->in_parent && node_is_right_child(node))
129 node = node->in_parent;
130 return node->in_parent;
133 static struct interval_node *interval_prev(struct interval_node *node)
139 return interval_last(node->in_left);
141 while (node->in_parent && node_is_left_child(node))
142 node = node->in_parent;
144 return node->in_parent;
147 enum interval_iter interval_iterate_reverse(struct interval_node *root,
148 interval_callback_t func,
151 enum interval_iter rc = INTERVAL_ITER_CONT;
152 struct interval_node *node;
154 for (node = interval_last(root); node; node = interval_prev(node)) {
155 rc = func(node, data);
156 if (rc == INTERVAL_ITER_STOP)
162 EXPORT_SYMBOL(interval_iterate_reverse);
164 static void __rotate_change_maxhigh(struct interval_node *node,
165 struct interval_node *rotate)
167 __u64 left_max, right_max;
169 rotate->in_max_high = node->in_max_high;
170 left_max = node->in_left ? node->in_left->in_max_high : 0;
171 right_max = node->in_right ? node->in_right->in_max_high : 0;
172 node->in_max_high = max(interval_high(node),
173 max(left_max, right_max));
176 /* The left rotation "pivots" around the link from node to node->right, and
177 * - node will be linked to node->right's left child, and
178 * - node->right's left child will be linked to node's right child.
180 static void __rotate_left(struct interval_node *node,
181 struct interval_node **root)
183 struct interval_node *right = node->in_right;
184 struct interval_node *parent = node->in_parent;
186 node->in_right = right->in_left;
188 right->in_left->in_parent = node;
190 right->in_left = node;
191 right->in_parent = parent;
193 if (node_is_left_child(node))
194 parent->in_left = right;
196 parent->in_right = right;
200 node->in_parent = right;
202 /* update max_high for node and right */
203 __rotate_change_maxhigh(node, right);
206 /* The right rotation "pivots" around the link from node to node->left, and
207 * - node will be linked to node->left's right child, and
208 * - node->left's right child will be linked to node's left child.
210 static void __rotate_right(struct interval_node *node,
211 struct interval_node **root)
213 struct interval_node *left = node->in_left;
214 struct interval_node *parent = node->in_parent;
216 node->in_left = left->in_right;
218 left->in_right->in_parent = node;
219 left->in_right = node;
221 left->in_parent = parent;
223 if (node_is_right_child(node))
224 parent->in_right = left;
226 parent->in_left = left;
230 node->in_parent = left;
232 /* update max_high for node and left */
233 __rotate_change_maxhigh(node, left);
236 #define interval_swap(a, b) do { \
237 struct interval_node *c = a; a = b; b = c; \
241 * Operations INSERT and DELETE, when run on a tree with n keys,
242 * take O(logN) time.Because they modify the tree, the result
243 * may violate the red-black properties.To restore these properties,
244 * we must change the colors of some of the nodes in the tree
245 * and also change the pointer structure.
247 static void interval_insert_color(struct interval_node *node,
248 struct interval_node **root)
250 struct interval_node *parent, *gparent;
252 while ((parent = node->in_parent) && node_is_red(parent)) {
253 gparent = parent->in_parent;
254 /* Parent is RED, so gparent must not be NULL */
255 if (node_is_left_child(parent)) {
256 struct interval_node *uncle;
258 uncle = gparent->in_right;
259 if (uncle && node_is_red(uncle)) {
260 uncle->in_color = INTERVAL_BLACK;
261 parent->in_color = INTERVAL_BLACK;
262 gparent->in_color = INTERVAL_RED;
267 if (parent->in_right == node) {
268 __rotate_left(parent, root);
269 interval_swap(node, parent);
272 parent->in_color = INTERVAL_BLACK;
273 gparent->in_color = INTERVAL_RED;
274 __rotate_right(gparent, root);
276 struct interval_node *uncle;
278 uncle = gparent->in_left;
279 if (uncle && node_is_red(uncle)) {
280 uncle->in_color = INTERVAL_BLACK;
281 parent->in_color = INTERVAL_BLACK;
282 gparent->in_color = INTERVAL_RED;
287 if (node_is_left_child(node)) {
288 __rotate_right(parent, root);
289 interval_swap(node, parent);
292 parent->in_color = INTERVAL_BLACK;
293 gparent->in_color = INTERVAL_RED;
294 __rotate_left(gparent, root);
298 (*root)->in_color = INTERVAL_BLACK;
301 struct interval_node *interval_insert(struct interval_node *node,
302 struct interval_node **root)
305 struct interval_node **p, *parent = NULL;
307 LASSERT(!interval_is_intree(node));
311 if (node_equal(parent, node))
314 /* max_high field must be updated after each iteration */
315 if (parent->in_max_high < interval_high(node))
316 parent->in_max_high = interval_high(node);
318 if (extent_compare(&node->in_extent, &parent->in_extent) < 0)
319 p = &parent->in_left;
321 p = &parent->in_right;
324 /* link node into the tree */
325 node->in_parent = parent;
326 node->in_color = INTERVAL_RED;
327 node->in_left = NULL;
328 node->in_right = NULL;
331 interval_insert_color(node, root);
336 EXPORT_SYMBOL(interval_insert);
338 static inline int node_is_black_or_0(struct interval_node *node)
340 return !node || node_is_black(node);
343 static void interval_erase_color(struct interval_node *node,
344 struct interval_node *parent,
345 struct interval_node **root)
347 struct interval_node *tmp;
349 while (node_is_black_or_0(node) && node != *root) {
350 if (parent->in_left == node) {
351 tmp = parent->in_right;
352 if (node_is_red(tmp)) {
353 tmp->in_color = INTERVAL_BLACK;
354 parent->in_color = INTERVAL_RED;
355 __rotate_left(parent, root);
356 tmp = parent->in_right;
358 if (node_is_black_or_0(tmp->in_left) &&
359 node_is_black_or_0(tmp->in_right)) {
360 tmp->in_color = INTERVAL_RED;
362 parent = node->in_parent;
364 if (node_is_black_or_0(tmp->in_right)) {
365 struct interval_node *o_left;
367 o_left = tmp->in_left;
369 o_left->in_color = INTERVAL_BLACK;
370 tmp->in_color = INTERVAL_RED;
371 __rotate_right(tmp, root);
372 tmp = parent->in_right;
374 tmp->in_color = parent->in_color;
375 parent->in_color = INTERVAL_BLACK;
377 tmp->in_right->in_color = INTERVAL_BLACK;
378 __rotate_left(parent, root);
383 tmp = parent->in_left;
384 if (node_is_red(tmp)) {
385 tmp->in_color = INTERVAL_BLACK;
386 parent->in_color = INTERVAL_RED;
387 __rotate_right(parent, root);
388 tmp = parent->in_left;
390 if (node_is_black_or_0(tmp->in_left) &&
391 node_is_black_or_0(tmp->in_right)) {
392 tmp->in_color = INTERVAL_RED;
394 parent = node->in_parent;
396 if (node_is_black_or_0(tmp->in_left)) {
397 struct interval_node *o_right;
399 o_right = tmp->in_right;
401 o_right->in_color = INTERVAL_BLACK;
402 tmp->in_color = INTERVAL_RED;
403 __rotate_left(tmp, root);
404 tmp = parent->in_left;
406 tmp->in_color = parent->in_color;
407 parent->in_color = INTERVAL_BLACK;
409 tmp->in_left->in_color = INTERVAL_BLACK;
410 __rotate_right(parent, root);
417 node->in_color = INTERVAL_BLACK;
421 * if the @max_high value of @node is changed, this function traverse a path
422 * from node up to the root to update max_high for the whole tree.
424 static void update_maxhigh(struct interval_node *node,
427 __u64 left_max, right_max;
430 left_max = node->in_left ? node->in_left->in_max_high : 0;
431 right_max = node->in_right ? node->in_right->in_max_high : 0;
432 node->in_max_high = max(interval_high(node),
433 max(left_max, right_max));
435 if (node->in_max_high >= old_maxhigh)
437 node = node->in_parent;
441 void interval_erase(struct interval_node *node,
442 struct interval_node **root)
444 struct interval_node *child, *parent;
447 LASSERT(interval_is_intree(node));
449 if (!node->in_left) {
450 child = node->in_right;
451 } else if (!node->in_right) {
452 child = node->in_left;
453 } else { /* Both left and right child are not NULL */
454 struct interval_node *old = node;
456 node = interval_next(node);
457 child = node->in_right;
458 parent = node->in_parent;
459 color = node->in_color;
462 child->in_parent = parent;
464 parent->in_right = child;
466 parent->in_left = child;
468 node->in_color = old->in_color;
469 node->in_right = old->in_right;
470 node->in_left = old->in_left;
471 node->in_parent = old->in_parent;
473 if (old->in_parent) {
474 if (node_is_left_child(old))
475 old->in_parent->in_left = node;
477 old->in_parent->in_right = node;
482 old->in_left->in_parent = node;
484 old->in_right->in_parent = node;
485 update_maxhigh(child ? : parent, node->in_max_high);
486 update_maxhigh(node, old->in_max_high);
491 parent = node->in_parent;
492 color = node->in_color;
495 child->in_parent = parent;
497 if (node_is_left_child(node))
498 parent->in_left = child;
500 parent->in_right = child;
505 update_maxhigh(child ? : parent, node->in_max_high);
508 if (color == INTERVAL_BLACK)
509 interval_erase_color(child, parent, root);
511 EXPORT_SYMBOL(interval_erase);
513 static inline int interval_may_overlap(struct interval_node *node,
514 struct interval_node_extent *ext)
516 return (ext->start <= node->in_max_high &&
517 ext->end >= interval_low(node));
521 * This function finds all intervals that overlap interval ext,
522 * and calls func to handle resulted intervals one by one.
523 * in lustre, this function will find all conflicting locks in
524 * the granted queue and add these locks to the ast work list.
529 * if (ext->end < interval_low(node)) {
530 * interval_search(node->in_left, ext, func, data);
531 * } else if (interval_may_overlap(node, ext)) {
532 * if (extent_overlapped(ext, &node->in_extent))
534 * interval_search(node->in_left, ext, func, data);
535 * interval_search(node->in_right, ext, func, data);
541 enum interval_iter interval_search(struct interval_node *node,
542 struct interval_node_extent *ext,
543 interval_callback_t func,
546 enum interval_iter rc = INTERVAL_ITER_CONT;
547 struct interval_node *parent;
553 if (ext->end < interval_low(node)) {
555 node = node->in_left;
558 } else if (interval_may_overlap(node, ext)) {
559 if (extent_overlapped(ext, &node->in_extent)) {
560 rc = func(node, data);
561 if (rc == INTERVAL_ITER_STOP)
566 node = node->in_left;
569 if (node->in_right) {
570 node = node->in_right;
575 parent = node->in_parent;
577 if (node_is_left_child(node) &&
580 * If we ever got the left, it means that the
581 * parent met ext->end<interval_low(parent), or
582 * may_overlap(parent). If the former is true,
583 * we needn't go back. So stop early and check
584 * may_overlap(parent) after this loop.
586 node = parent->in_right;
590 parent = parent->in_parent;
592 if (!parent || !interval_may_overlap(parent, ext))
598 EXPORT_SYMBOL(interval_search);