Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

702 lines
18 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. redblack.fnc
  5. Abstract:
  6. This module implements the red/black trees via macros for structure
  7. field independence (so that we can use the same code with different
  8. fields by just redefining the macros). This file is included by
  9. redblack.c, which also defines the function names.
  10. Author:
  11. 16-Jun-1995 t-orig
  12. Credits:
  13. This code is largly based on pseud-code by Cormen, Leiserson and Rivest
  14. in "Introduction to Algorithms", MIT press, 1989: QA76.6.C662
  15. Revision History:
  16. --*/
  17. /* --
  18. INTRODUCTION:
  19. A red/black tree is a binary tree with the following properties:
  20. 1) Every node is either red or black
  21. 2) Every leaf (NIL, **NOT** NULL) is black. Note that in our implementation
  22. this is accomplished by having all leaves be NIL which is black by
  23. definition.
  24. 3) If a node is red, then both its children are black
  25. 4) Every simple path from a node to a descendent leaf contains the same
  26. number of black nodes
  27. These properties imply that every red/black tree is "approximately balanced",
  28. thus red/black trees have logarithmic time operations. The find operation
  29. is identical to that of a regular binary tree, and is thus especially fast.
  30. Insert and delete operations are complicated by the fact that after the
  31. regular binary tree operation, one must take special care to ensure that the
  32. red/black properties hold for the new tree. This is accomplished via right
  33. and left rotations.
  34. Note that the empty tree is denoted by NIL, not NULL. NIL is an actual
  35. node passed to all the red/black tree functions, and greatly simplifies
  36. coding by eliminating special cases (this also yields faster running time).
  37. -- */
  38. PEPNODE
  39. LEFT_ROTATE(
  40. PEPNODE root,
  41. PEPNODE x,
  42. PEPNODE NIL
  43. )
  44. /*++
  45. Routine Description:
  46. Rotates the tree to the left at node x.
  47. x y
  48. / \ / \
  49. A y ==>> x C
  50. / \ / \
  51. B C A B
  52. Arguments:
  53. root - The root of the Red/Black tree
  54. x - The node at which to rotate
  55. Return Value:
  56. return-value - The new root of the tree (which could be the same as
  57. the old root).
  58. --*/
  59. {
  60. PEPNODE y;
  61. y = RIGHT(x);
  62. RIGHT(x) = LEFT(y);
  63. if (LEFT(y) != NIL){
  64. PARENT(LEFT(y)) = x;
  65. }
  66. PARENT(y) = PARENT(x);
  67. if (PARENT(x) == NIL){
  68. root = y;
  69. } else if (x==LEFT(PARENT(x))) {
  70. LEFT(PARENT(x)) = y;
  71. } else {
  72. RIGHT(PARENT(x))= y;
  73. }
  74. LEFT(y) = x;
  75. PARENT(x) = y;
  76. return root;
  77. }
  78. PEPNODE
  79. RIGHT_ROTATE(
  80. PEPNODE root,
  81. PEPNODE x,
  82. PEPNODE NIL
  83. )
  84. /*++
  85. Routine Description:
  86. Rotates the tree to the right at node x.
  87. x y
  88. / \ / \
  89. y C ==>> A x
  90. / \ / \
  91. A B B C
  92. Arguments:
  93. root - The root of the Red/Black tree
  94. x - The node at which to rotate
  95. Return Value:
  96. return-value - The new root of the tree (which could be the same as
  97. the old root).
  98. --*/
  99. {
  100. PEPNODE y;
  101. y = LEFT(x);
  102. LEFT(x) = RIGHT(y);
  103. if (RIGHT(y) != NIL) {
  104. PARENT(RIGHT(y)) = x;
  105. }
  106. PARENT(y) = PARENT(x);
  107. if (PARENT(x) == NIL) {
  108. root = y;
  109. } else if (x==LEFT(PARENT(x))) {
  110. LEFT(PARENT(x)) = y;
  111. } else {
  112. RIGHT(PARENT(x))= y;
  113. }
  114. RIGHT(y) = x;
  115. PARENT(x) = y;
  116. return root;
  117. }
  118. PEPNODE
  119. TREE_INSERT(
  120. PEPNODE root,
  121. PEPNODE z,
  122. PEPNODE NIL
  123. )
  124. /*++
  125. Routine Description:
  126. Inserts a new node into a tree without preserving the red/black properties.
  127. Should ONLY be called by RB_INSERT! This is just a simple binary tree
  128. insertion routine.
  129. Arguments:
  130. root - The root of the red/black tree
  131. z - The new node to insert
  132. Return Value:
  133. return-value - The new root of the tree (which could be the same as the
  134. old root).
  135. --*/
  136. {
  137. PEPNODE x,y;
  138. y = NIL;
  139. x = root;
  140. LEFT(z) = RIGHT(z) = NIL;
  141. // Find a place to insert z by doing a simple binary search
  142. while (x!=NIL) {
  143. y = x;
  144. if (KEY(z) < KEY(x)){
  145. x = LEFT(x);
  146. } else {
  147. x = RIGHT(x);
  148. }
  149. }
  150. // Insert z into the tree
  151. PARENT(z)= y;
  152. if (y==NIL) {
  153. root = z;
  154. } else if (KEY(z)<KEY(y)) {
  155. LEFT(y) = z;
  156. } else {
  157. RIGHT(y) = z;
  158. }
  159. return root;
  160. }
  161. PEPNODE
  162. RB_INSERT(
  163. PEPNODE root,
  164. PEPNODE x,
  165. PEPNODE NIL
  166. )
  167. /*++
  168. Routine Description:
  169. Inserts a node into a red/black tree while preserving the red/black
  170. properties.
  171. Arguments:
  172. root - The root of the red/black tree
  173. z - The new node to insert
  174. Return Value:
  175. return-value - The new root of the tree (which could be the same as
  176. the old root).
  177. --*/
  178. {
  179. PEPNODE y;
  180. // Insert x into the tree without preserving the red/black properties
  181. root = TREE_INSERT (root, x, NIL);
  182. COLOR(x) = RED;
  183. // We can stop fixing the tree when either:
  184. // 1) We got to the root
  185. // 2) x has a BLACK parent (the tree obeys the red/black properties,
  186. // because no RED parent has a RED child.
  187. while ((x != root) && (COLOR(PARENT(x)) == RED)) {
  188. if (PARENT(x) == LEFT(PARENT(PARENT(x)))) {
  189. // Parent of x is a left child with sibling y.
  190. y = RIGHT(PARENT(PARENT(x)));
  191. if (COLOR(y) == RED) {
  192. // Since y is red, just change everyone's color and try again
  193. // with x's grandfather
  194. COLOR (PARENT (x)) = BLACK;
  195. COLOR(y) = BLACK;
  196. COLOR(PARENT(PARENT(x))) = RED;
  197. x = PARENT(PARENT(x));
  198. } else if (x == RIGHT (PARENT (x))) {
  199. // Here y is BLACK and x is a right child. A left rotation
  200. // at x would prepare us for the next case
  201. x = PARENT(x);
  202. root = LEFT_ROTATE (root, x, NIL);
  203. } else {
  204. // Here y is BLACK and x is a left child. We fix the tree by
  205. // switching the colors of x's parent and grandparent and
  206. // doing a right rotation at x's grandparent.
  207. COLOR (PARENT (x)) = BLACK;
  208. COLOR (PARENT (PARENT (x))) = RED;
  209. root = RIGHT_ROTATE (root, PARENT(PARENT(x)), NIL);
  210. }
  211. } else {
  212. // Parent of x is a right child with sibling y.
  213. y = LEFT(PARENT(PARENT(x)));
  214. if (COLOR(y) == RED) {
  215. // Since y is red, just change everyone's color and try again
  216. // with x's grandfather
  217. COLOR (PARENT (x)) = BLACK;
  218. COLOR(y) = BLACK;
  219. COLOR(PARENT(PARENT(x))) = RED;
  220. x = PARENT(PARENT(x));
  221. } else if (x == LEFT (PARENT (x))) {
  222. // Here y is BLACK and x is a left child. A right rotation
  223. // at x would prepare us for the next case
  224. x = PARENT(x);
  225. root = RIGHT_ROTATE (root, x, NIL);
  226. } else {
  227. // Here y is BLACK and x is a right child. We fix the tree by
  228. // switching the colors of x's parent and grandparent and
  229. // doing a left rotation at x's grandparent.
  230. COLOR (PARENT (x)) = BLACK;
  231. COLOR (PARENT (PARENT (x))) = RED;
  232. root = LEFT_ROTATE (root, PARENT(PARENT(x)), NIL);
  233. }
  234. }
  235. } // end of while loop
  236. COLOR(root) = BLACK;
  237. return root;
  238. }
  239. PEPNODE
  240. FIND(
  241. PEPNODE root,
  242. PVOID addr,
  243. PEPNODE NIL
  244. )
  245. /*++
  246. Routine Description:
  247. Finds a node in the red black tree given an address (key)
  248. Arguments:
  249. root - The root of the red/black tree
  250. addr - The address corresponding to the node to be searched for.
  251. Return Value:
  252. return-value - The node in the tree (entry point of code containing address), or
  253. NULL if not found.
  254. --*/
  255. {
  256. while (root != NIL) {
  257. if (addr < START(root)) {
  258. root = LEFT(root);
  259. } else if (addr > END(root)) {
  260. root = RIGHT(root);
  261. } else {
  262. return root;
  263. }
  264. }
  265. return NULL; // Range not found
  266. }
  267. BOOLEAN
  268. CONTAINSRANGE(
  269. PEPNODE root,
  270. PEPNODE NIL,
  271. PVOID StartAddr,
  272. PVOID EndAddr
  273. )
  274. /*++
  275. Routine Description:
  276. Decides if any part of the specified range is represented by a node
  277. in the tree.
  278. Arguments:
  279. root - The root of the red/black tree
  280. NIL - NIL pointer for the tree
  281. StartAddr - starting address of the range
  282. EndAddr - ending address of the range
  283. Return Value:
  284. TRUE if any byte of the range is inside a node of the tree.
  285. FALSE otherwise (no overlap between any entrypoint and the range)
  286. --*/
  287. {
  288. while (root != NIL) {
  289. if (StartAddr <= START(root) && START(root) <= EndAddr) {
  290. // START(root) is within the range
  291. return TRUE;
  292. }
  293. if (StartAddr <= END(root) && END(root) <= EndAddr) {
  294. // END(root) is within the range
  295. return TRUE;
  296. }
  297. if (StartAddr < START(root)) {
  298. root = LEFT(root);
  299. } else {
  300. root = RIGHT(root);
  301. }
  302. }
  303. return FALSE; // Range is not stored within the tree
  304. }
  305. PEPNODE
  306. FINDNEXT(
  307. PEPNODE root,
  308. PVOID addr,
  309. PEPNODE NIL
  310. )
  311. /*++
  312. Routine Description:
  313. Finds a node in the red black tree which follows the given address
  314. Arguments:
  315. root - The root of the red/black tree
  316. addr - The address which comes just before the node
  317. Return Value:
  318. return-value - The node in the tree (entry point of code containing address), or
  319. NULL if not found.
  320. --*/
  321. {
  322. PEPNODE pNode;
  323. // If the tree is empty, there is no next node...
  324. if (root==NIL){
  325. return NULL;
  326. }
  327. // Now go down to a leaf
  328. while (root != NIL) {
  329. if (addr < START(root)) {
  330. pNode=root;
  331. root = LEFT(root);
  332. } else {
  333. pNode=root;
  334. root = RIGHT(root);
  335. }
  336. }
  337. while (addr > START(pNode)){
  338. if (PARENT(pNode) == NIL){
  339. return NULL; // There is no successor
  340. }
  341. pNode = PARENT(pNode);
  342. }
  343. return pNode;
  344. }
  345. PEPNODE
  346. TREE_SUCCESSOR(
  347. PEPNODE x,
  348. PEPNODE NIL
  349. )
  350. /*++
  351. Routine Description:
  352. Returns the successor of a node in a binary tree (the successor of x
  353. is defined to be the node which just follows x in an inorder
  354. traversal of the tree).
  355. Arguments:
  356. x - The node whose successor is to be returned
  357. Return Value:
  358. return-value - The successor of x
  359. --*/
  360. {
  361. PEPNODE y;
  362. // If x has a right child, the successor is the leftmost node to the
  363. // right of x.
  364. if (RIGHT(x) != NIL) {
  365. x = RIGHT(x);
  366. while (LEFT(x) != NIL) {
  367. x = LEFT(x);
  368. }
  369. return x;
  370. }
  371. // Else the successor is an ancestor with a left child on the path to x
  372. y = PARENT(x);
  373. while ((y != NIL) && (x == RIGHT(y))) {
  374. x = y;
  375. y = PARENT(y);
  376. }
  377. return y;
  378. }
  379. PEPNODE
  380. RB_DELETE_FIXUP(
  381. PEPNODE root,
  382. PEPNODE x,
  383. PEPNODE NIL
  384. )
  385. /*++
  386. Routine Description:
  387. Fixes the red/black tree after a delete operation. Should only be
  388. called by RB_DELETE
  389. Arguments:
  390. root - The root of the red/black tree
  391. x - Either a child of x, or or a child or x's successor
  392. Return Value:
  393. return-value - The new root of the red/black tree
  394. --*/
  395. {
  396. PEPNODE w;
  397. // We stop when we either reached the root, or reached a red node (which
  398. // means that property 4 is no longer violated).
  399. while ((x!=root) && (COLOR(x)==BLACK)) {
  400. if (x == LEFT(PARENT(x))) {
  401. // x is a left child with sibling w
  402. w = RIGHT(PARENT(x));
  403. if (COLOR(w) == RED) {
  404. // If w is red it must have black children. We can switch
  405. // the colors of w and its parent and perform a left
  406. // rotation to bring w to the top. This brings us to one
  407. // of the other cases.
  408. COLOR(w) = BLACK;
  409. COLOR(PARENT(x)) = RED;
  410. root = LEFT_ROTATE (root, PARENT(x), NIL);
  411. w = RIGHT(PARENT(x));
  412. }
  413. if ((COLOR(LEFT(w)) == BLACK) && (COLOR(RIGHT(w)) == BLACK)) {
  414. // Here w is black and has two black children. We can thus
  415. // change w's color to red and continue.
  416. COLOR(w) = RED;
  417. x = PARENT(x);
  418. } else {
  419. if (COLOR(RIGHT(w)) == BLACK) {
  420. // Here w is black, its left child is red, and its right child
  421. // is black. We switch the colors of w and its left child,
  422. // and perform a left rotation at w which brings us to the next
  423. // case.
  424. COLOR(LEFT(w)) = BLACK;
  425. COLOR(w) = RED;
  426. root = RIGHT_ROTATE (root, w, NIL);
  427. w = RIGHT(PARENT(x));
  428. }
  429. // Here w is black and has a red right child. We change w's
  430. // color to that of its parent, and make its parent and right
  431. // child black. Then a left rotation brings w to the top.
  432. // Making x the root ensures that the while loop terminates.
  433. COLOR(w) = COLOR(PARENT(x));
  434. COLOR(PARENT(x)) = BLACK;
  435. COLOR(RIGHT(w)) = BLACK;
  436. root = LEFT_ROTATE (root, PARENT(x), NIL);
  437. x = root;
  438. }
  439. } else {
  440. // The symmetric case: x is a right child with sibling w.
  441. w = LEFT(PARENT(x));
  442. if (COLOR(w) == RED) {
  443. COLOR(w) = BLACK;
  444. COLOR(PARENT(x)) = RED;
  445. root = RIGHT_ROTATE (root, PARENT(x), NIL);
  446. w = LEFT(PARENT(x));
  447. }
  448. if ((COLOR(LEFT(w)) == BLACK) && (COLOR(RIGHT(w)) == BLACK)) {
  449. COLOR(w) = RED;
  450. x = PARENT(x);
  451. } else {
  452. if (COLOR(LEFT(w)) == BLACK) {
  453. COLOR(RIGHT(w)) = BLACK;
  454. COLOR(w) = RED;
  455. root = LEFT_ROTATE (root, w, NIL);
  456. w = LEFT(PARENT(x));
  457. }
  458. COLOR(w) = COLOR(PARENT(x));
  459. COLOR(PARENT(x)) = BLACK;
  460. COLOR(LEFT(w)) = BLACK;
  461. root = RIGHT_ROTATE (root, PARENT(x), NIL);
  462. x = root;
  463. }
  464. }
  465. } // end of while loop
  466. //printf ("Changing color at %i to BLACK\n", x->intelColor);
  467. COLOR(x) = BLACK;
  468. return root;
  469. }
  470. PEPNODE
  471. RB_DELETE(
  472. PEPNODE root,
  473. PEPNODE z,
  474. PEPNODE NIL
  475. )
  476. /*++
  477. Routine Description:
  478. Deletes a node in a red/black tree while preserving the red/black
  479. properties.
  480. Arguments:
  481. root - The root of the red/black tree
  482. z - The node to be deleted
  483. Return Value:
  484. return-value - The new root of the red/black tree
  485. --*/
  486. {
  487. PEPNODE x,y;
  488. COL c;
  489. // It's easy to delete a node with at most one child: we only need to
  490. // remove it and put the child in its place. It z has at most one child,
  491. // we can just remove it. Otherwise we'll replace it with its successor
  492. // (which is guaranteed to have at most one child, or else one of its
  493. // children would be the succecssor), and delete the successor.
  494. if ((LEFT(z) == NIL) || (RIGHT(z) == NIL)) {
  495. y = z;
  496. } else {
  497. y = TREE_SUCCESSOR(z, NIL);
  498. }
  499. // Recall that y has at most one child. If y has one child, x is set to
  500. // it. Else x will be set to NIL which is OK. This way we don't have
  501. // to worry about this special case.
  502. if (LEFT(y) != NIL){
  503. x = LEFT(y);
  504. } else {
  505. x = RIGHT(y);
  506. }
  507. // Now we will remove y from the tree
  508. PARENT(x) = PARENT(y);
  509. if (PARENT(y) == NIL) {
  510. root = x;
  511. } else if (y == LEFT(PARENT(y))) {
  512. LEFT(PARENT(y)) = x;
  513. } else {
  514. RIGHT(PARENT(y)) = x;
  515. }
  516. if (PARENT(x) == z) {
  517. PARENT(x) = y;
  518. }
  519. c = COLOR(y);
  520. // Since each node has lots of fields (fields may also change during
  521. // the lifetime of this code), I found it safer to copy the
  522. // pointers as opposed to data.
  523. if (y!=z) { // Now swapping y and z, but remembering color of y
  524. PARENT(y) = PARENT(z);
  525. if (root == z) {
  526. root = y;
  527. } else if (z == RIGHT(PARENT(z))) {
  528. RIGHT(PARENT(z)) = y;
  529. } else {
  530. LEFT(PARENT(z)) = y;
  531. }
  532. LEFT(y) = LEFT(z);
  533. if (LEFT(y) != NIL) {
  534. PARENT(LEFT(y)) = y;
  535. }
  536. RIGHT(y) = RIGHT(z);
  537. if (RIGHT(y) != NIL) {
  538. PARENT(RIGHT(y)) = y;
  539. }
  540. COLOR(y) = COLOR(z);
  541. }
  542. // Need to fix the tree (fourth red/black property).
  543. if (c == BLACK) {
  544. root = RB_DELETE_FIXUP (root, x, NIL);
  545. }
  546. return root;
  547. }