Coverage Report

Created: 2026-05-30 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/e2fsprogs/lib/ext2fs/rbtree.h
Line
Count
Source
1
/*
2
  Red Black Trees
3
  (C) 1999  Andrea Arcangeli <andrea@suse.de>
4
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU General Public License as published by
7
  the Free Software Foundation; either version 2 of the License, or
8
  (at your option) any later version.
9
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18
19
  linux/include/linux/rbtree.h
20
21
  To use rbtrees you'll have to implement your own insert and search cores.
22
  This will avoid us to use callbacks and to drop dramatically performances.
23
  I know it's not the cleaner way,  but in C (not in C++) to get
24
  performances and genericity...
25
26
  Some example of insert and search follows here. The search is a plain
27
  normal search over an ordered tree. The insert instead must be implemented
28
  in two steps: First, the code must insert the element in order as a red leaf
29
  in the tree, and then the support library function rb_insert_color() must
30
  be called. Such function will do the not trivial work to rebalance the
31
  rbtree, if necessary.
32
33
-----------------------------------------------------------------------
34
static inline struct page * rb_search_page_cache(struct inode * inode,
35
             unsigned long offset)
36
{
37
  struct rb_node * n = inode->i_rb_page_cache.rb_node;
38
  struct page * page;
39
40
  while (n)
41
  {
42
    page = rb_entry(n, struct page, rb_page_cache);
43
44
    if (offset < page->offset)
45
      n = n->rb_left;
46
    else if (offset > page->offset)
47
      n = n->rb_right;
48
    else
49
      return page;
50
  }
51
  return NULL;
52
}
53
54
static inline struct page * __rb_insert_page_cache(struct inode * inode,
55
               unsigned long offset,
56
               struct rb_node * node)
57
{
58
  struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
59
  struct rb_node * parent = NULL;
60
  struct page * page;
61
62
  while (*p)
63
  {
64
    parent = *p;
65
    page = rb_entry(parent, struct page, rb_page_cache);
66
67
    if (offset < page->offset)
68
      p = &(*p)->rb_left;
69
    else if (offset > page->offset)
70
      p = &(*p)->rb_right;
71
    else
72
      return page;
73
  }
74
75
  rb_link_node(node, parent, p);
76
77
  return NULL;
78
}
79
80
static inline struct page * rb_insert_page_cache(struct inode * inode,
81
             unsigned long offset,
82
             struct rb_node * node)
83
{
84
  struct page * ret;
85
  if ((ret = __rb_insert_page_cache(inode, offset, node)))
86
    goto out;
87
  rb_insert_color(node, &inode->i_rb_page_cache);
88
 out:
89
  return ret;
90
}
91
-----------------------------------------------------------------------
92
*/
93
94
#ifndef _LINUX_RBTREE_H
95
#define _LINUX_RBTREE_H
96
97
#include <stdlib.h>
98
#include <stdint.h>
99
#include "compiler.h"
100
101
#if __GNUC_PREREQ (4, 6)
102
#pragma GCC diagnostic push
103
#pragma GCC diagnostic ignored "-Wunused-function"
104
#endif
105
106
struct rb_node
107
{
108
  uintptr_t  rb_parent_color;
109
#define RB_RED    0
110
0
#define RB_BLACK  1
111
  struct rb_node *rb_right;
112
  struct rb_node *rb_left;
113
} __attribute__((aligned(sizeof(long))));
114
    /* The alignment might seem pointless, but allegedly CRIS needs it */
115
116
struct rb_root
117
{
118
  struct rb_node *rb_node;
119
};
120
121
122
0
#define ext2fs_rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
123
0
#define ext2fs_rb_color(r)   ((r)->rb_parent_color & 1)
124
0
#define ext2fs_rb_is_red(r)   (!ext2fs_rb_color(r))
125
0
#define ext2fs_rb_is_black(r) ext2fs_rb_color(r)
126
0
#define ext2fs_rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
127
0
#define ext2fs_rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
128
129
static inline void ext2fs_rb_set_parent(struct rb_node *rb, struct rb_node *p)
130
0
{
131
0
  rb->rb_parent_color = (rb->rb_parent_color & 3) | (uintptr_t)p;
132
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_set_parent
Unexecuted instantiation: rbtree.c:ext2fs_rb_set_parent
133
static inline void ext2fs_rb_set_color(struct rb_node *rb, int color)
134
0
{
135
0
  rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
136
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_set_color
Unexecuted instantiation: rbtree.c:ext2fs_rb_set_color
137
138
0
#define RB_ROOT (struct rb_root) { NULL, }
139
#define ext2fs_rb_entry(ptr, type, member) container_of(ptr, type, member)
140
141
static inline int ext2fs_rb_empty_root(struct rb_root *root)
142
0
{
143
0
  return root->rb_node == NULL;
144
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_empty_root
Unexecuted instantiation: rbtree.c:ext2fs_rb_empty_root
145
146
static inline int ext2fs_rb_empty_node(struct rb_node *node)
147
0
{
148
0
  return ext2fs_rb_parent(node) == node;
149
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_empty_node
Unexecuted instantiation: rbtree.c:ext2fs_rb_empty_node
150
151
static inline void ext2fs_rb_clear_node(struct rb_node *node)
152
0
{
153
0
  ext2fs_rb_set_parent(node, node);
154
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_clear_node
Unexecuted instantiation: rbtree.c:ext2fs_rb_clear_node
155
156
extern void ext2fs_rb_insert_color(struct rb_node *, struct rb_root *);
157
extern void ext2fs_rb_erase(struct rb_node *, struct rb_root *);
158
159
/* Find logical next and previous nodes in a tree */
160
extern struct rb_node *ext2fs_rb_next(struct rb_node *);
161
extern struct rb_node *ext2fs_rb_prev(struct rb_node *);
162
extern struct rb_node *ext2fs_rb_first(const struct rb_root *);
163
extern struct rb_node *ext2fs_rb_last(const struct rb_root *);
164
165
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
166
extern void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new_,
167
         struct rb_root *root);
168
169
static inline void ext2fs_rb_link_node(struct rb_node * node,
170
             struct rb_node * parent,
171
             struct rb_node ** rb_link)
172
0
{
173
0
  node->rb_parent_color = (uintptr_t)parent;
174
0
  node->rb_left = node->rb_right = NULL;
175
176
0
  *rb_link = node;
177
0
}
Unexecuted instantiation: blkmap64_rb.c:ext2fs_rb_link_node
Unexecuted instantiation: rbtree.c:ext2fs_rb_link_node
178
179
#if __GNUC_PREREQ (4, 6)
180
#pragma GCC diagnostic pop
181
#endif
182
183
#endif  /* _LINUX_RBTREE_H */