Index: sys/sys/tree.h =================================================================== --- sys/sys/tree.h +++ sys/sys/tree.h @@ -340,6 +340,7 @@ #define RB_RED_MASK ((__uintptr_t)3) #define RB_FLIP_LEFT(elm, field) (RB_BITS(elm, field) ^= RB_RED_L) #define RB_FLIP_RIGHT(elm, field) (RB_BITS(elm, field) ^= RB_RED_R) +#define RB_FLIP_ALL(elm, field) (RB_BITS(elm, field) ^= RB_RED_MASK) #define RB_RED_LEFT(elm, field) ((RB_BITS(elm, field) & RB_RED_L) != 0) #define RB_RED_RIGHT(elm, field) ((RB_BITS(elm, field) & RB_RED_R) != 0) #define RB_PARENT(elm, field) ((__typeof(RB_UP(elm, field))) \ @@ -477,11 +478,12 @@ continue; \ } \ if (!RB_RED_RIGHT(elm, field)) { \ - RB_FLIP_LEFT(elm, field); \ RB_ROTATE_LEFT(head, elm, child, field);\ if (RB_RED_LEFT(child, field)) \ - RB_FLIP_RIGHT(elm, field); \ - else if (RB_RED_RIGHT(child, field)) \ + RB_FLIP_ALL(elm, field); \ + else \ + RB_FLIP_LEFT(elm, field); \ + if (RB_RED_RIGHT(child, field)) \ RB_FLIP_LEFT(parent, field); \ elm = child; \ } \ @@ -497,11 +499,12 @@ continue; \ } \ if (!RB_RED_LEFT(elm, field)) { \ - RB_FLIP_RIGHT(elm, field); \ RB_ROTATE_RIGHT(head, elm, child, field);\ if (RB_RED_RIGHT(child, field)) \ - RB_FLIP_LEFT(elm, field); \ - else if (RB_RED_LEFT(child, field)) \ + RB_FLIP_ALL(elm, field); \ + else \ + RB_FLIP_RIGHT(elm, field); \ + if (RB_RED_LEFT(child, field)) \ RB_FLIP_RIGHT(parent, field); \ elm = child; \ } \ @@ -538,23 +541,30 @@ continue; \ } \ sib = RB_RIGHT(parent, field); \ - if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\ - RB_BITS(sib, field) &= ~RB_RED_MASK; \ + switch (RB_BITS(sib, field) & RB_RED_MASK) { \ + case RB_RED_MASK: \ + RB_FLIP_ALL(sib, field); \ elm = parent; \ continue; \ - } \ - RB_FLIP_RIGHT(sib, field); \ - if (RB_RED_LEFT(sib, field)) \ - RB_FLIP_LEFT(parent, field); \ - else if (!RB_RED_RIGHT(sib, field)) { \ - RB_FLIP_LEFT(parent, field); \ + case RB_RED_R: \ RB_ROTATE_RIGHT(head, sib, elm, field); \ - if (RB_RED_RIGHT(elm, field)) \ - RB_FLIP_LEFT(sib, field); \ if (RB_RED_LEFT(elm, field)) \ - RB_FLIP_RIGHT(parent, field); \ + RB_FLIP_ALL(parent, field); \ + else \ + RB_FLIP_LEFT(parent, field); \ + if (RB_RED_RIGHT(elm, field)) \ + RB_FLIP_ALL(sib, field); \ + else \ + RB_FLIP_RIGHT(sib, field); \ RB_BITS(elm, field) |= RB_RED_MASK; \ sib = elm; \ + break; \ + case RB_RED_L: \ + RB_FLIP_LEFT(parent, field); \ + /* fallthrough - see footnote[1] */ \ + default: \ + RB_FLIP_RIGHT(sib, field); \ + break; \ } \ RB_ROTATE_LEFT(head, parent, sib, field); \ } else { \ @@ -568,26 +578,40 @@ continue; \ } \ sib = RB_LEFT(parent, field); \ - if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\ - RB_BITS(sib, field) &= ~RB_RED_MASK; \ + switch (RB_BITS(sib, field) & RB_RED_MASK) { \ + case RB_RED_MASK: \ + RB_FLIP_ALL(sib, field); \ elm = parent; \ continue; \ - } \ - RB_FLIP_LEFT(sib, field); \ - if (RB_RED_RIGHT(sib, field)) \ - RB_FLIP_RIGHT(parent, field); \ - else if (!RB_RED_LEFT(sib, field)) { \ - RB_FLIP_RIGHT(parent, field); \ + case RB_RED_L: \ RB_ROTATE_LEFT(head, sib, elm, field); \ - if (RB_RED_LEFT(elm, field)) \ - RB_FLIP_RIGHT(sib, field); \ if (RB_RED_RIGHT(elm, field)) \ - RB_FLIP_LEFT(parent, field); \ + RB_FLIP_ALL(parent, field); \ + else \ + RB_FLIP_RIGHT(parent, field); \ + if (RB_RED_LEFT(elm, field)) \ + RB_FLIP_ALL(sib, field); \ + else \ + RB_FLIP_LEFT(sib, field); \ RB_BITS(elm, field) |= RB_RED_MASK; \ sib = elm; \ + break; \ + case RB_RED_R: \ + RB_FLIP_RIGHT(parent, field); \ + /* fallthrough - see footnote [1] */ \ + default: \ + RB_FLIP_LEFT(sib, field); \ + break; \ } \ RB_ROTATE_RIGHT(head, parent, sib, field); \ } \ + /* \ + * [1] - In this case the HST paper, figure 3, has \ + * parent with one higher rank, and then reduces the \ + * rank if parent has become a leaf. This \ + * implementation always has the parent in its new \ + * position with lower rank, to avoid the leaf check. \ + */ \ break; \ } while ((parent = RB_PARENT(elm, field)) != NULL); \ }