annotate libitm/aatree.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1 /* Copyright (C) 2009-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
2 Contributed by Richard Henderson <rth@redhat.com>.
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of the GNU Transactional Memory Library (libitm).
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 Libitm is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
7 under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
8 the Free Software Foundation; either version 3 of the License, or
kono
parents:
diff changeset
9 (at your option) any later version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 Libitm is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
kono
parents:
diff changeset
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kono
parents:
diff changeset
14 more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
17 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
18 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
21 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
23 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 /* Implements an AA tree (http://en.wikipedia.org/wiki/AA_tree) with an
kono
parents:
diff changeset
26 integer key, and data attached to the node via flexible array member. */
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #ifndef LIBITM_AATREE_H
kono
parents:
diff changeset
29 #define LIBITM_AATREE_H 1
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 namespace GTM HIDDEN {
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 template<typename KEY> class aa_tree_key;
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 class aa_node_base
kono
parents:
diff changeset
36 {
kono
parents:
diff changeset
37 public:
kono
parents:
diff changeset
38 static const bool L = false;
kono
parents:
diff changeset
39 static const bool R = true;
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 private:
kono
parents:
diff changeset
42 typedef unsigned int level_type;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 aa_node_base *m_link[2];
kono
parents:
diff changeset
45 level_type m_level;
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 static const aa_node_base s_nil;
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 public:
kono
parents:
diff changeset
50 aa_node_base(level_type l = 1)
kono
parents:
diff changeset
51 : m_link { const_cast<aa_node_base *>(&s_nil),
kono
parents:
diff changeset
52 const_cast<aa_node_base *>(&s_nil) },
kono
parents:
diff changeset
53 m_level(l)
kono
parents:
diff changeset
54 { }
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 bool is_nil() const { return this == &s_nil; }
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 aa_node_base * link(bool d) { return m_link[d]; }
kono
parents:
diff changeset
59 void set_link(bool d, aa_node_base *val) { m_link[d] = val; }
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 aa_node_base *skew();
kono
parents:
diff changeset
62 aa_node_base *split();
kono
parents:
diff changeset
63 void decrease_level();
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 static void *operator new (size_t s) { return xmalloc (s); }
kono
parents:
diff changeset
66 static void operator delete (void *p) { free (p); }
kono
parents:
diff changeset
67 };
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 template<typename KEY>
kono
parents:
diff changeset
70 struct aa_node_key : public aa_node_base
kono
parents:
diff changeset
71 {
kono
parents:
diff changeset
72 typedef aa_node_base base;
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 KEY key;
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 explicit aa_node_key(KEY k) : key(k) { }
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 aa_node_key * link(bool d)
kono
parents:
diff changeset
79 {
kono
parents:
diff changeset
80 return static_cast<aa_node_key *>(base::link(d));
kono
parents:
diff changeset
81 }
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 aa_node_key *skew() { return static_cast<aa_node_key *>(base::skew()); }
kono
parents:
diff changeset
84 aa_node_key *split() { return static_cast<aa_node_key *>(base::split()); }
kono
parents:
diff changeset
85 };
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 template<typename KEY, typename DATA>
kono
parents:
diff changeset
88 struct aa_node : public aa_node_key<KEY>
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 typedef aa_node_key<KEY> base;
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 DATA data;
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 explicit aa_node(KEY k) : base(k) { }
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 aa_node * link(bool d)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 return static_cast<aa_node *>(base::link(d));
kono
parents:
diff changeset
99 }
kono
parents:
diff changeset
100 };
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 template<typename KEY>
kono
parents:
diff changeset
103 class aa_tree_key
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 public:
kono
parents:
diff changeset
106 typedef aa_node_key<KEY> node;
kono
parents:
diff changeset
107 typedef node *node_ptr;
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 protected:
kono
parents:
diff changeset
110 node_ptr m_tree;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 protected:
kono
parents:
diff changeset
113 aa_tree_key() : m_tree(0) { }
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 node_ptr find(KEY k) const;
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 static node_ptr insert_1 (node_ptr t, node_ptr n);
kono
parents:
diff changeset
118 void insert(node_ptr n);
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 static node_ptr erase_1 (node_ptr t, KEY k, node_ptr *pfree);
kono
parents:
diff changeset
121 node_ptr erase(KEY k);
kono
parents:
diff changeset
122 };
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 extern template class aa_tree_key<uintptr_t>;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 template<typename KEY, typename DATA>
kono
parents:
diff changeset
127 class aa_tree : public aa_tree_key<KEY>
kono
parents:
diff changeset
128 {
kono
parents:
diff changeset
129 public:
kono
parents:
diff changeset
130 typedef aa_tree_key<KEY> base;
kono
parents:
diff changeset
131 typedef aa_node<KEY, DATA> node;
kono
parents:
diff changeset
132 typedef node *node_ptr;
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 typedef void (*trav_callback)(KEY, DATA *, void *);
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 private:
kono
parents:
diff changeset
137 static void clear_1 (node_ptr);
kono
parents:
diff changeset
138 static void traverse_1 (node_ptr, trav_callback, void *);
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 public:
kono
parents:
diff changeset
141 aa_tree() = default;
kono
parents:
diff changeset
142 ~aa_tree() { clear(); }
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 static void *operator new (size_t s, aa_tree<KEY, DATA>* p) { return p; }
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 DATA *find(KEY k) const
kono
parents:
diff changeset
147 {
kono
parents:
diff changeset
148 node_ptr n = static_cast<node_ptr>(base::find (k));
kono
parents:
diff changeset
149 return n ? &n->data : 0;
kono
parents:
diff changeset
150 }
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 DATA *insert(KEY k)
kono
parents:
diff changeset
153 {
kono
parents:
diff changeset
154 node_ptr n = new node(k);
kono
parents:
diff changeset
155 base::insert(n);
kono
parents:
diff changeset
156 return &n->data;
kono
parents:
diff changeset
157 }
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 void erase(KEY k)
kono
parents:
diff changeset
160 {
kono
parents:
diff changeset
161 node_ptr n = static_cast<node_ptr>(base::erase (k));
kono
parents:
diff changeset
162 delete n;
kono
parents:
diff changeset
163 }
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 node_ptr remove(KEY k, DATA** data)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 node_ptr n = static_cast<node_ptr>(base::erase (k));
kono
parents:
diff changeset
168 *data = (n ? &n->data : 0);
kono
parents:
diff changeset
169 return n;
kono
parents:
diff changeset
170 }
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 void clear()
kono
parents:
diff changeset
173 {
kono
parents:
diff changeset
174 node_ptr n = static_cast<node_ptr>(this->m_tree);
kono
parents:
diff changeset
175 if (n)
kono
parents:
diff changeset
176 {
kono
parents:
diff changeset
177 this->m_tree = 0;
kono
parents:
diff changeset
178 clear_1 (n);
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 void traverse (trav_callback cb, void *cb_data)
kono
parents:
diff changeset
183 {
kono
parents:
diff changeset
184 node_ptr t = static_cast<node_ptr>(this->m_tree);
kono
parents:
diff changeset
185 if (t != 0)
kono
parents:
diff changeset
186 traverse_1 (t, cb, cb_data);
kono
parents:
diff changeset
187 }
kono
parents:
diff changeset
188 };
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 template<typename KEY, typename DATA>
kono
parents:
diff changeset
192 void
kono
parents:
diff changeset
193 aa_tree<KEY, DATA>::clear_1 (node_ptr t)
kono
parents:
diff changeset
194 {
kono
parents:
diff changeset
195 if (t->is_nil())
kono
parents:
diff changeset
196 return;
kono
parents:
diff changeset
197 clear_1 (t->link(node::L));
kono
parents:
diff changeset
198 clear_1 (t->link(node::R));
kono
parents:
diff changeset
199 delete t;
kono
parents:
diff changeset
200 }
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 template<typename KEY, typename DATA>
kono
parents:
diff changeset
203 void
kono
parents:
diff changeset
204 aa_tree<KEY, DATA>::traverse_1 (node_ptr t, trav_callback cb, void *cb_data)
kono
parents:
diff changeset
205 {
kono
parents:
diff changeset
206 if (t->is_nil())
kono
parents:
diff changeset
207 return;
kono
parents:
diff changeset
208 cb (t->key, &t->data, cb_data);
kono
parents:
diff changeset
209 traverse_1 (t->link(node::L), cb, cb_data);
kono
parents:
diff changeset
210 traverse_1 (t->link(node::R), cb, cb_data);
kono
parents:
diff changeset
211 }
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 } // namespace GTM
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 #endif // LIBITM_AATREE_H