@@ -14,6 +14,54 @@ using namespace vm;
14
14
15
15
namespace {
16
16
17
+ class TreeContext {
18
+ public:
19
+ class Path {
20
+ public:
21
+ Path (object node, Path* next): node(node), next(next) { }
22
+
23
+ object node;
24
+ Path* next;
25
+ };
26
+
27
+ class MyProtector : public Thread ::Protector {
28
+ public:
29
+ MyProtector (Thread* thread, TreeContext* context):
30
+ Protector (thread), context(context)
31
+ { }
32
+
33
+ virtual void visit (Heap::Visitor* v) {
34
+ v->visit (&(context->root ));
35
+ v->visit (&(context->node ));
36
+
37
+ for (Path* p = context->ancestors ; p; p = p->next ) {
38
+ v->visit (&(p->node ));
39
+ }
40
+ }
41
+
42
+ TreeContext* context;
43
+ };
44
+
45
+ TreeContext (Thread* thread, Zone* zone):
46
+ zone (zone), root(0 ), node(0 ), ancestors(0 ), protector(thread, this ),
47
+ fresh (false )
48
+ { }
49
+
50
+ Zone* zone;
51
+ object root;
52
+ object node;
53
+ Path* ancestors;
54
+ MyProtector protector;
55
+ bool fresh;
56
+ };
57
+
58
+ TreeContext::Path*
59
+ path (TreeContext* c, object node, TreeContext::Path* next)
60
+ {
61
+ return new (c->zone ->allocate (sizeof (TreeContext::Path)))
62
+ TreeContext::Path (node, next);
63
+ }
64
+
17
65
inline object
18
66
getTreeNodeValue (Thread*, object n)
19
67
{
@@ -58,8 +106,9 @@ cloneTreeNode(Thread* t, object n)
58
106
return newNode;
59
107
}
60
108
61
- object
62
- treeFind (Thread* t, object old, intptr_t key, object node, object sentinal,
109
+ void
110
+ treeFind (Thread* t, TreeContext* c, object old, intptr_t key, object node,
111
+ object sentinal,
63
112
intptr_t (*compare)(Thread* t, intptr_t key, object b))
64
113
{
65
114
PROTECT (t, old);
@@ -72,11 +121,8 @@ treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
72
121
object new_ = newRoot;
73
122
PROTECT (t, new_);
74
123
75
- object ancestors = 0 ;
76
- PROTECT (t, ancestors);
77
-
78
124
while (old != sentinal) {
79
- ancestors = makePair (t , new_, ancestors);
125
+ c-> ancestors = path (c , new_, c-> ancestors );
80
126
81
127
intptr_t difference = compare (t, key, getTreeNodeValue (t, old));
82
128
@@ -91,13 +137,20 @@ treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
91
137
set (t, new_, TreeNodeRight, n);
92
138
new_ = n;
93
139
} else {
94
- return makeTreePath (t, false , new_, newRoot, pairSecond (t, ancestors));
140
+ c->fresh = false ;
141
+ c->root = newRoot;
142
+ c->node = new_;
143
+ c->ancestors = c->ancestors ->next ;
144
+ return ;
95
145
}
96
146
}
97
147
98
148
setTreeNodeValue (t, new_, getTreeNodeValue (t, node));
99
149
100
- return makeTreePath (t, true , new_, newRoot, ancestors);
150
+ c->fresh = true ;
151
+ c->root = newRoot;
152
+ c->node = new_;
153
+ c->ancestors = c->ancestors ;
101
154
}
102
155
103
156
object
@@ -123,122 +176,109 @@ rightRotate(Thread* t, object n)
123
176
}
124
177
125
178
object
126
- treeAdd (Thread* t, object path )
179
+ treeAdd (Thread* t, TreeContext* c )
127
180
{
128
- object new_ = treePathNode (t, path) ;
181
+ object new_ = c-> node ;
129
182
PROTECT (t, new_);
130
183
131
- object newRoot = treePathRoot (t, path) ;
184
+ object newRoot = c-> root ;
132
185
PROTECT (t, newRoot);
133
186
134
- object ancestors = treePathAncestors (t, path);
135
- PROTECT (t, ancestors);
136
-
137
187
// rebalance
138
188
setTreeNodeRed (t, new_, true );
139
- while (ancestors != 0 and treeNodeRed (t, pairFirst (t, ancestors) )) {
140
- if (pairFirst (t, ancestors)
141
- == treeNodeLeft (t, pairFirst (t, pairSecond (t, ancestors)) ))
189
+ while (c-> ancestors != 0 and treeNodeRed (t, c-> ancestors -> node )) {
190
+ if (c-> ancestors -> node
191
+ == treeNodeLeft (t, c-> ancestors -> next -> node ))
142
192
{
143
193
if (treeNodeRed
144
- (t, treeNodeRight (t, pairFirst (t, pairSecond (t, ancestors)) )))
194
+ (t, treeNodeRight (t, c-> ancestors -> next -> node )))
145
195
{
146
- setTreeNodeRed (t, pairFirst (t, ancestors) , false );
196
+ setTreeNodeRed (t, c-> ancestors -> node , false );
147
197
148
198
object n = cloneTreeNode
149
- (t, treeNodeRight (t, pairFirst (t, pairSecond (t, ancestors)) ));
199
+ (t, treeNodeRight (t, c-> ancestors -> next -> node ));
150
200
151
- set (t, pairFirst (t, pairSecond (t, ancestors)) , TreeNodeRight, n);
201
+ set (t, c-> ancestors -> next -> node , TreeNodeRight, n);
152
202
153
- setTreeNodeRed
154
- (t, treeNodeRight
155
- (t, pairFirst (t, pairSecond (t, ancestors))), false );
203
+ setTreeNodeRed (t, treeNodeRight (t, c->ancestors ->next ->node ), false );
156
204
157
- setTreeNodeRed (t, pairFirst (t, pairSecond (t, ancestors)) , true );
205
+ setTreeNodeRed (t, c-> ancestors -> next -> node , true );
158
206
159
- new_ = pairFirst (t, pairSecond (t, ancestors)) ;
160
- ancestors = pairSecond (t, pairSecond (t, ancestors)) ;
207
+ new_ = c-> ancestors -> next -> node ;
208
+ c-> ancestors = c-> ancestors -> next -> next ;
161
209
} else {
162
- if (new_ == treeNodeRight (t, pairFirst (t, ancestors) )) {
163
- new_ = pairFirst (t, ancestors) ;
164
- ancestors = pairSecond (t, ancestors) ;
210
+ if (new_ == treeNodeRight (t, c-> ancestors -> node )) {
211
+ new_ = c-> ancestors -> node ;
212
+ c-> ancestors = c-> ancestors -> next ;
165
213
166
214
object n = leftRotate (t, new_);
167
215
168
- if (new_ == treeNodeRight (t, pairFirst (t, ancestors) )) {
169
- set (t, pairFirst (t, ancestors) , TreeNodeRight, n);
216
+ if (new_ == treeNodeRight (t, c-> ancestors -> node )) {
217
+ set (t, c-> ancestors -> node , TreeNodeRight, n);
170
218
} else {
171
- set (t, pairFirst (t, ancestors) , TreeNodeLeft, n);
219
+ set (t, c-> ancestors -> node , TreeNodeLeft, n);
172
220
}
173
- ancestors = makePair (t , n, ancestors);
221
+ c-> ancestors = path (c , n, c-> ancestors );
174
222
}
175
- setTreeNodeRed (t, pairFirst (t, ancestors) , false );
176
- setTreeNodeRed (t, pairFirst (t, pairSecond (t, ancestors)) , true );
223
+ setTreeNodeRed (t, c-> ancestors -> node , false );
224
+ setTreeNodeRed (t, c-> ancestors -> next -> node , true );
177
225
178
- object n = rightRotate (t, pairFirst (t, pairSecond (t, ancestors)) );
179
- if (pairSecond (t, pairSecond (t, ancestors)) == 0 ) {
226
+ object n = rightRotate (t, c-> ancestors -> next -> node );
227
+ if (c-> ancestors -> next -> next == 0 ) {
180
228
newRoot = n;
181
- } else if (treeNodeRight
182
- (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))))
183
- == pairFirst (t, pairSecond (t, ancestors)))
229
+ } else if (treeNodeRight (t, c->ancestors ->next ->next ->node )
230
+ == c->ancestors ->next ->node )
184
231
{
185
- set (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))),
186
- TreeNodeRight, n);
232
+ set (t, c->ancestors ->next ->next ->node , TreeNodeRight, n);
187
233
} else {
188
- set (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))),
189
- TreeNodeLeft, n);
234
+ set (t, c->ancestors ->next ->next ->node , TreeNodeLeft, n);
190
235
}
191
236
// done
192
237
}
193
238
} else { // this is just the reverse of the code above (right and
194
239
// left swapped):
195
240
if (treeNodeRed
196
- (t, treeNodeLeft (t, pairFirst (t, pairSecond (t, ancestors)) )))
241
+ (t, treeNodeLeft (t, c-> ancestors -> next -> node )))
197
242
{
198
- setTreeNodeRed (t, pairFirst (t, ancestors) , false );
243
+ setTreeNodeRed (t, c-> ancestors -> node , false );
199
244
200
245
object n = cloneTreeNode
201
- (t, treeNodeLeft (t, pairFirst (t, pairSecond (t, ancestors)) ));
246
+ (t, treeNodeLeft (t, c-> ancestors -> next -> node ));
202
247
203
- set (t, pairFirst (t, pairSecond (t, ancestors)) , TreeNodeLeft, n);
248
+ set (t, c-> ancestors -> next -> node , TreeNodeLeft, n);
204
249
205
- setTreeNodeRed
206
- (t, treeNodeLeft
207
- (t, pairFirst (t, pairSecond (t, ancestors))), false );
250
+ setTreeNodeRed (t, treeNodeLeft (t, c->ancestors ->next ->node ), false );
208
251
209
- setTreeNodeRed (t, pairFirst (t, pairSecond (t, ancestors)) , true );
252
+ setTreeNodeRed (t, c-> ancestors -> next -> node , true );
210
253
211
- new_ = pairFirst (t, pairSecond (t, ancestors)) ;
212
- ancestors = pairSecond (t, pairSecond (t, ancestors)) ;
254
+ new_ = c-> ancestors -> next -> node ;
255
+ c-> ancestors = c-> ancestors -> next -> next ;
213
256
} else {
214
- if (new_ == treeNodeLeft (t, pairFirst (t, ancestors) )) {
215
- new_ = pairFirst (t, ancestors) ;
216
- ancestors = pairSecond (t, ancestors) ;
257
+ if (new_ == treeNodeLeft (t, c-> ancestors -> node )) {
258
+ new_ = c-> ancestors -> node ;
259
+ c-> ancestors = c-> ancestors -> next ;
217
260
218
261
object n = rightRotate (t, new_);
219
262
220
- if (new_ == treeNodeLeft (t, pairFirst (t, ancestors) )) {
221
- set (t, pairFirst (t, ancestors) , TreeNodeLeft, n);
263
+ if (new_ == treeNodeLeft (t, c-> ancestors -> node )) {
264
+ set (t, c-> ancestors -> node , TreeNodeLeft, n);
222
265
} else {
223
- set (t, pairFirst (t, ancestors) , TreeNodeRight, n);
266
+ set (t, c-> ancestors -> node , TreeNodeRight, n);
224
267
}
225
- ancestors = makePair (t , n, ancestors);
268
+ c-> ancestors = path (c , n, c-> ancestors );
226
269
}
227
- setTreeNodeRed (t, pairFirst (t, ancestors) , false );
228
- setTreeNodeRed (t, pairFirst (t, pairSecond (t, ancestors)) , true );
270
+ setTreeNodeRed (t, c-> ancestors -> node , false );
271
+ setTreeNodeRed (t, c-> ancestors -> next -> node , true );
229
272
230
- object n = leftRotate (t, pairFirst (t, pairSecond (t, ancestors)) );
231
- if (pairSecond (t, pairSecond (t, ancestors)) == 0 ) {
273
+ object n = leftRotate (t, c-> ancestors -> next -> node );
274
+ if (c-> ancestors -> next -> next == 0 ) {
232
275
newRoot = n;
233
- } else if (treeNodeLeft
234
- (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))))
235
- == pairFirst (t, pairSecond (t, ancestors)))
276
+ } else if (treeNodeLeft (t, c->ancestors ->next ->next ->node )
277
+ == c->ancestors ->next ->node )
236
278
{
237
- set (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))),
238
- TreeNodeLeft, n);
279
+ set (t, c->ancestors ->next ->next ->node , TreeNodeLeft, n);
239
280
} else {
240
- set (t, pairFirst (t, pairSecond (t, pairSecond (t, ancestors))),
241
- TreeNodeRight, n);
281
+ set (t, c->ancestors ->next ->next ->node , TreeNodeRight, n);
242
282
}
243
283
// done
244
284
}
@@ -541,16 +581,18 @@ treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
541
581
}
542
582
543
583
object
544
- treeInsertNode (Thread* t, object tree, intptr_t key, object node,
584
+ treeInsertNode (Thread* t, Zone* zone, object tree, intptr_t key, object node,
545
585
object sentinal,
546
586
intptr_t (*compare)(Thread* t, intptr_t key, object b))
547
587
{
548
588
PROTECT (t, tree);
549
589
PROTECT (t, sentinal);
550
590
551
- object path = treeFind (t, tree, key, node, sentinal, compare);
552
- expect (t, treePathFresh (t, path));
553
- return treeAdd (t, path);
591
+ TreeContext c (t, zone);
592
+ treeFind (t, &c, tree, key, node, sentinal, compare);
593
+ expect (t, c.fresh );
594
+
595
+ return treeAdd (t, &c);
554
596
}
555
597
556
598
} // namespace vm
0 commit comments