Skip to content

Commit ff6602f

Browse files
committed
set: start working on join
for faster set algos and pctl
1 parent cfed9b0 commit ff6602f

File tree

1 file changed

+140
-7
lines changed

1 file changed

+140
-7
lines changed

ctl/set.h

Lines changed: 140 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,8 @@ static inline A JOIN(A, init_from)(A *copy)
252252
{
253253
static A zero;
254254
A self = zero;
255-
#ifdef POD
256-
self.copy = JOIN(A, implicit_copy);
257-
#else
258-
self.free = JOIN(T, free);
259-
self.copy = JOIN(T, copy);
260-
#endif
255+
self.copy = from->copy;
256+
self.free = from->free;
261257
self.compare = copy->compare;
262258
self.equal = copy->equal;
263259
return self;
@@ -942,7 +938,144 @@ static inline void JOIN(A, erase_generic)(A* self, GI *range)
942938
}
943939
}
944940

945-
static inline A JOIN(A, intersection)(A *a, A *b)
941+
// join and split for fast bulk insert, bulk erase and the algos below.
942+
// also needed for pctl.
943+
static inline size_t
944+
JOIN(B, rank)(B* node)
945+
{
946+
size_t count = 0;
947+
while (node) {
948+
if (!node->r) {
949+
count++;
950+
}
951+
node = node->l;
952+
}
953+
return count;
954+
}
955+
956+
#ifdef DEBUG
957+
958+
// From https://arxiv.org/pdf/1602.02120.pdf
959+
// or also called concatenate sometimes
960+
static inline A *JOIN(A, join_right)(A *left, T key, B *right)
961+
{
962+
// require the 3 parts to be ordered:
963+
ASSERT(left->compare(JOIN(B, max)(left->root), key));
964+
ASSERT(left->compare(key, JOIN(B, min)(right->root)));
965+
// same black height
966+
if (JOIN(B, rank)(left->root) == (JOIN(B, rank)(right->root) / 2) * 2)
967+
{
968+
B *old = left->root;
969+
int color = JOIN(B, is_black)(left->root) & JOIN(B, is_black)(right->root) ? 0 : 1;
970+
left->root = JOIN(B, init)(key, color);
971+
left->root->l = old;
972+
left->root->r = right->root;
973+
left->size += right->size + 1;
974+
return left;
975+
}
976+
else
977+
{
978+
B *l1 = left->root->l;
979+
B *r1 = left->root->r;
980+
T k1 = left->root->key;
981+
int c1 = left->root->color;
982+
A new_t = JOIN(A, init_from)(left);
983+
new_t->root = r1;
984+
new_t->root->r = join_right(&new_r, key, right);
985+
new_t->root->l = l1;
986+
new_t->key = k1;
987+
new_t->color = c1;
988+
/*
989+
if(c == black) and (c(R(T′)) == c(R(R(T′))) == red)
990+
{
991+
c(R(R(T′))) = black;
992+
JOIN(A, rotate_l)(new_t);
993+
}
994+
*/
995+
return new_t;
996+
}
997+
}
998+
999+
static inline A*
1000+
JOIN(A, join_left)(A* left, T key, B* right)
1001+
{
1002+
// require the 3 parts to be ordered
1003+
ASSERT(left->compare(JOIN(B, max)(left->root), key));
1004+
ASSERT(left->compare(key, JOIN(B, min)(right->root)));
1005+
/*
1006+
if r(TL)/2 > r(TR)/2
1007+
T′ = join_right(TL, k, TR);
1008+
if(c(T′) == red) and (c(R(T′))=red) then
1009+
Node(L(T′),〈k(T′),black〉, R(T′))
1010+
else T′
1011+
else if r(TR)/2c>br(TL)/2 then
1012+
T′ = join_left(TL, k, TR);
1013+
if (c(T′)==red) and (c(L(T′)) == red)
1014+
Node(L(T′),〈k(T′),black〉, R(T′));
1015+
else
1016+
T′
1017+
else if (c(TL) == black and c(TR) == black)
1018+
Node(TL,〈k,red〉, TR)
1019+
else
1020+
Node(TL,〈k,black〉, TR)
1021+
*/
1022+
}
1023+
1024+
/*
1025+
split(T, k) =
1026+
if T=Leaf then (Leaf,false,Leaf)
1027+
else (L, m, R) = expose(T);
1028+
if k=m then (L,true,R)
1029+
else if k < m then
1030+
(LL, b, LR) = split(L, k);
1031+
(LL,b,join(LR, m, R))
1032+
else
1033+
(RL, b, RR) =split(R, k);
1034+
(join(L, m, RL), b, RR)
1035+
1036+
splitLast(T) =
1037+
(L, k, R) =expose(T);
1038+
if R=Leaf then (L, k)
1039+
else (T′, k′) =splitLast(R);
1040+
(join(L, k, T′),k′)
1041+
1042+
join2(TL,TR) =
1043+
if TL=Leaf then TR
1044+
else (T′L, k) =splitLast(TL);
1045+
join(T′L, k, TR)
1046+
1047+
union(T1,T2) =
1048+
if T1=Leaf then T2
1049+
else if T2=Leaf then T1
1050+
else
1051+
(L2,k2,R2) =expose(T2);
1052+
(L1,b,R1) =split(T1,k2);
1053+
TL=union(L1,L2)‖TR=union(R1,R2);
1054+
join(TL,k2,TR)
1055+
1056+
intersect(T1,T2) =
1057+
if T1=Leaf then Leaf
1058+
else if T2=Leaf then Leaf
1059+
else
1060+
(L2,k2,R2) =expose(T2);
1061+
(L1,b,R1) =split(T1,k2);
1062+
TL=intersect(L1,L2)‖TR=intersect(R1,R2);
1063+
if b=true then join(TL,k2,TR)
1064+
else join2(TL,TR)
1065+
1066+
difference(T1,T2) =
1067+
if T1=Leaf then Leaf
1068+
else if T2=Leaf then T1
1069+
else
1070+
(L2,k2,R2) =expose(T2);
1071+
(L1,b,R1) =split(T1,k2);
1072+
TL=difference(L1,L2)‖TR=difference(R1,R2);
1073+
join2(TL,TR)
1074+
*/
1075+
1076+
#endif
1077+
1078+
static inline A JOIN(A, intersection)(A* a, A* b)
9461079
{
9471080
A self = JOIN(A, init_from)(a);
9481081
B *node = JOIN(A, first)(a);

0 commit comments

Comments
 (0)