Subversion Repositories Kolibri OS

Rev

Rev 5270 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5270 Rev 6934
Line 42... Line 42...
42
 *  We shall indicate color with case, where black nodes are uppercase and red
42
 *  We shall indicate color with case, where black nodes are uppercase and red
43
 *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
43
 *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
44
 *  parentheses and have some accompanying text comment.
44
 *  parentheses and have some accompanying text comment.
45
 */
45
 */
Line -... Line 46...
-
 
46
 
-
 
47
/*
-
 
48
 * Notes on lockless lookups:
-
 
49
 *
-
 
50
 * All stores to the tree structure (rb_left and rb_right) must be done using
-
 
51
 * WRITE_ONCE(). And we must not inadvertently cause (temporary) loops in the
-
 
52
 * tree structure as seen in program order.
-
 
53
 *
-
 
54
 * These two requirements will allow lockless iteration of the tree -- not
-
 
55
 * correct iteration mind you, tree rotations are not atomic so a lookup might
-
 
56
 * miss entire subtrees.
-
 
57
 *
-
 
58
 * But they do guarantee that any such traversal will only see valid elements
-
 
59
 * and that it will indeed complete -- does not get stuck in a loop.
-
 
60
 *
-
 
61
 * It also guarantees that if the lookup returns an element it is the 'correct'
-
 
62
 * one. But not returning an element does _NOT_ mean it's not present.
-
 
63
 *
-
 
64
 * NOTE:
-
 
65
 *
-
 
66
 * Stores to __rb_parent_color are not important for simple lookups so those
-
 
67
 * are left undone as of now. Nor did I check for loops involving parent
-
 
68
 * pointers.
-
 
69
 */
46
 
70
 
47
static inline void rb_set_black(struct rb_node *rb)
71
static inline void rb_set_black(struct rb_node *rb)
48
{
72
{
49
	rb->__rb_parent_color |= RB_BLACK;
73
	rb->__rb_parent_color |= RB_BLACK;
Line 127... Line 151...
127
				 *      n         p
151
				 *      n         p
128
				 *
152
				 *
129
				 * This still leaves us in violation of 4), the
153
				 * This still leaves us in violation of 4), the
130
				 * continuation into Case 3 will fix that.
154
				 * continuation into Case 3 will fix that.
131
				 */
155
				 */
132
				parent->rb_right = tmp = node->rb_left;
156
				tmp = node->rb_left;
-
 
157
				WRITE_ONCE(parent->rb_right, tmp);
133
				node->rb_left = parent;
158
				WRITE_ONCE(node->rb_left, parent);
134
				if (tmp)
159
				if (tmp)
135
					rb_set_parent_color(tmp, parent,
160
					rb_set_parent_color(tmp, parent,
136
							    RB_BLACK);
161
							    RB_BLACK);
137
				rb_set_parent_color(parent, node, RB_RED);
162
				rb_set_parent_color(parent, node, RB_RED);
138
				augment_rotate(parent, node);
163
				augment_rotate(parent, node);
Line 147... Line 172...
147
			 *       / \         / \
172
			 *       / \         / \
148
			 *      p   U  -->  n   g
173
			 *      p   U  -->  n   g
149
			 *     /                 \
174
			 *     /                 \
150
			 *    n                   U
175
			 *    n                   U
151
			 */
176
			 */
152
			gparent->rb_left = tmp;  /* == parent->rb_right */
177
			WRITE_ONCE(gparent->rb_left, tmp); /* == parent->rb_right */
153
			parent->rb_right = gparent;
178
			WRITE_ONCE(parent->rb_right, gparent);
154
			if (tmp)
179
			if (tmp)
155
				rb_set_parent_color(tmp, gparent, RB_BLACK);
180
				rb_set_parent_color(tmp, gparent, RB_BLACK);
156
			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
181
			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
157
			augment_rotate(gparent, parent);
182
			augment_rotate(gparent, parent);
158
			break;
183
			break;
Line 169... Line 194...
169
			}
194
			}
Line 170... Line 195...
170
 
195
 
171
			tmp = parent->rb_left;
196
			tmp = parent->rb_left;
172
			if (node == tmp) {
197
			if (node == tmp) {
173
				/* Case 2 - right rotate at parent */
198
				/* Case 2 - right rotate at parent */
-
 
199
				tmp = node->rb_right;
174
				parent->rb_left = tmp = node->rb_right;
200
				WRITE_ONCE(parent->rb_left, tmp);
175
				node->rb_right = parent;
201
				WRITE_ONCE(node->rb_right, parent);
176
				if (tmp)
202
				if (tmp)
177
					rb_set_parent_color(tmp, parent,
203
					rb_set_parent_color(tmp, parent,
178
							    RB_BLACK);
204
							    RB_BLACK);
179
				rb_set_parent_color(parent, node, RB_RED);
205
				rb_set_parent_color(parent, node, RB_RED);
180
				augment_rotate(parent, node);
206
				augment_rotate(parent, node);
181
				parent = node;
207
				parent = node;
182
				tmp = node->rb_left;
208
				tmp = node->rb_left;
Line 183... Line 209...
183
			}
209
			}
184
 
210
 
185
			/* Case 3 - left rotate at gparent */
211
			/* Case 3 - left rotate at gparent */
186
			gparent->rb_right = tmp;  /* == parent->rb_left */
212
			WRITE_ONCE(gparent->rb_right, tmp); /* == parent->rb_left */
187
			parent->rb_left = gparent;
213
			WRITE_ONCE(parent->rb_left, gparent);
188
			if (tmp)
214
			if (tmp)
189
				rb_set_parent_color(tmp, gparent, RB_BLACK);
215
				rb_set_parent_color(tmp, gparent, RB_BLACK);
190
			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
216
			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
Line 222... Line 248...
222
				 *    / \             / \
248
				 *    / \             / \
223
				 *   N   s    -->    p   Sr
249
				 *   N   s    -->    p   Sr
224
				 *      / \         / \
250
				 *      / \         / \
225
				 *     Sl  Sr      N   Sl
251
				 *     Sl  Sr      N   Sl
226
				 */
252
				 */
227
				parent->rb_right = tmp1 = sibling->rb_left;
253
				tmp1 = sibling->rb_left;
-
 
254
				WRITE_ONCE(parent->rb_right, tmp1);
228
				sibling->rb_left = parent;
255
				WRITE_ONCE(sibling->rb_left, parent);
229
				rb_set_parent_color(tmp1, parent, RB_BLACK);
256
				rb_set_parent_color(tmp1, parent, RB_BLACK);
230
				__rb_rotate_set_parents(parent, sibling, root,
257
				__rb_rotate_set_parents(parent, sibling, root,
231
							RB_RED);
258
							RB_RED);
232
				augment_rotate(parent, sibling);
259
				augment_rotate(parent, sibling);
233
				sibling = tmp1;
260
				sibling = tmp1;
Line 273... Line 300...
273
				 *     / \             \
300
				 *     / \             \
274
				 *    sl  Sr            s
301
				 *    sl  Sr            s
275
				 *                       \
302
				 *                       \
276
				 *                        Sr
303
				 *                        Sr
277
				 */
304
				 */
278
				sibling->rb_left = tmp1 = tmp2->rb_right;
305
				tmp1 = tmp2->rb_right;
-
 
306
				WRITE_ONCE(sibling->rb_left, tmp1);
279
				tmp2->rb_right = sibling;
307
				WRITE_ONCE(tmp2->rb_right, sibling);
280
				parent->rb_right = tmp2;
308
				WRITE_ONCE(parent->rb_right, tmp2);
281
				if (tmp1)
309
				if (tmp1)
282
					rb_set_parent_color(tmp1, sibling,
310
					rb_set_parent_color(tmp1, sibling,
283
							    RB_BLACK);
311
							    RB_BLACK);
284
				augment_rotate(sibling, tmp2);
312
				augment_rotate(sibling, tmp2);
285
				tmp1 = sibling;
313
				tmp1 = sibling;
Line 295... Line 323...
295
			 *      / \             / \
323
			 *      / \             / \
296
			 *     N   S     -->   P   Sr
324
			 *     N   S     -->   P   Sr
297
			 *        / \         / \
325
			 *        / \         / \
298
			 *      (sl) sr      N  (sl)
326
			 *      (sl) sr      N  (sl)
299
			 */
327
			 */
300
			parent->rb_right = tmp2 = sibling->rb_left;
328
			tmp2 = sibling->rb_left;
-
 
329
			WRITE_ONCE(parent->rb_right, tmp2);
301
			sibling->rb_left = parent;
330
			WRITE_ONCE(sibling->rb_left, parent);
302
			rb_set_parent_color(tmp1, sibling, RB_BLACK);
331
			rb_set_parent_color(tmp1, sibling, RB_BLACK);
303
			if (tmp2)
332
			if (tmp2)
304
				rb_set_parent(tmp2, parent);
333
				rb_set_parent(tmp2, parent);
305
			__rb_rotate_set_parents(parent, sibling, root,
334
			__rb_rotate_set_parents(parent, sibling, root,
306
						RB_BLACK);
335
						RB_BLACK);
Line 308... Line 337...
308
			break;
337
			break;
309
		} else {
338
		} else {
310
			sibling = parent->rb_left;
339
			sibling = parent->rb_left;
311
			if (rb_is_red(sibling)) {
340
			if (rb_is_red(sibling)) {
312
				/* Case 1 - right rotate at parent */
341
				/* Case 1 - right rotate at parent */
313
				parent->rb_left = tmp1 = sibling->rb_right;
342
				tmp1 = sibling->rb_right;
-
 
343
				WRITE_ONCE(parent->rb_left, tmp1);
314
				sibling->rb_right = parent;
344
				WRITE_ONCE(sibling->rb_right, parent);
315
				rb_set_parent_color(tmp1, parent, RB_BLACK);
345
				rb_set_parent_color(tmp1, parent, RB_BLACK);
316
				__rb_rotate_set_parents(parent, sibling, root,
346
				__rb_rotate_set_parents(parent, sibling, root,
317
							RB_RED);
347
							RB_RED);
318
				augment_rotate(parent, sibling);
348
				augment_rotate(parent, sibling);
319
				sibling = tmp1;
349
				sibling = tmp1;
Line 334... Line 364...
334
							continue;
364
							continue;
335
					}
365
					}
336
					break;
366
					break;
337
				}
367
				}
338
				/* Case 3 - right rotate at sibling */
368
				/* Case 3 - right rotate at sibling */
339
				sibling->rb_right = tmp1 = tmp2->rb_left;
369
				tmp1 = tmp2->rb_left;
-
 
370
				WRITE_ONCE(sibling->rb_right, tmp1);
340
				tmp2->rb_left = sibling;
371
				WRITE_ONCE(tmp2->rb_left, sibling);
341
				parent->rb_left = tmp2;
372
				WRITE_ONCE(parent->rb_left, tmp2);
342
				if (tmp1)
373
				if (tmp1)
343
					rb_set_parent_color(tmp1, sibling,
374
					rb_set_parent_color(tmp1, sibling,
344
							    RB_BLACK);
375
							    RB_BLACK);
345
				augment_rotate(sibling, tmp2);
376
				augment_rotate(sibling, tmp2);
346
				tmp1 = sibling;
377
				tmp1 = sibling;
347
				sibling = tmp2;
378
				sibling = tmp2;
348
			}
379
			}
349
			/* Case 4 - left rotate at parent + color flips */
380
			/* Case 4 - left rotate at parent + color flips */
350
			parent->rb_left = tmp2 = sibling->rb_right;
381
			tmp2 = sibling->rb_right;
-
 
382
			WRITE_ONCE(parent->rb_left, tmp2);
351
			sibling->rb_right = parent;
383
			WRITE_ONCE(sibling->rb_right, parent);
352
			rb_set_parent_color(tmp1, sibling, RB_BLACK);
384
			rb_set_parent_color(tmp1, sibling, RB_BLACK);
353
			if (tmp2)
385
			if (tmp2)
354
				rb_set_parent(tmp2, parent);
386
				rb_set_parent(tmp2, parent);
355
			__rb_rotate_set_parents(parent, sibling, root,
387
			__rb_rotate_set_parents(parent, sibling, root,
356
						RB_BLACK);
388
						RB_BLACK);