31 const std::shared_ptr<const Node>& lft,
34 const std::shared_ptr<const Node>& rgt) :
42 total_serialized_size = map::get_serialized_size_with_padding(key) +
43 map::get_serialized_size_with_padding(val);
46 total_size += lft->size();
47 total_serialized_size += lft->serialized_size();
51 total_size += rgt->size();
52 total_serialized_size += rgt->serialized_size();
57 std::shared_ptr<const Node> _lft;
60 std::shared_ptr<const Node> _rgt;
61 size_t total_size = 0;
62 size_t total_serialized_size = 0;
69 size_t serialized_size()
const
71 return total_serialized_size;
75 explicit Map(std::shared_ptr<const Node>
const& node) : _root(node) {}
83 std::optional<size_t>
size = std::nullopt) :
84 _root(std::make_shared<const Node>(c, lft._root, key, val, rgt._root))
86 assert(lft.
empty() || lft.rootKey() < key);
87 assert(rgt.
empty() || key < rgt.rootKey());
104 return empty() ? 0 : _root->size();
109 return empty() ? 0 : _root->serialized_size();
112 std::optional<V>
get(
const K& key)
const
122 const V*
getp(
const K& key)
const
130 return left().
getp(key);
132 return right().
getp(key);
137 Map put(
const K& key,
const V& value)
const
139 Map t = insert(key, value);
140 return Map(B, t.left(), t.rootKey(), t.rootValue(), t.right(), t.
size());
148 auto res = _remove(key);
149 if (res.second && res.first.rootColor() == R)
152 res.first =
Map(B, r.left(), r.rootKey(), r.rootValue(), r.right());
158 bool foreach(F&& f)
const
162 if (!left().
foreach(std::forward<F>(f)))
166 if (!f(rootKey(), rootValue()))
170 if (!right().
foreach(std::forward<F>(f)))
180 return std::make_unique<Snapshot>(*
this);
184 std::shared_ptr<const Node> _root;
186 Color rootColor()
const
199 const K& rootKey()
const
204 const V& rootValue()
const
211 return Map(_root->_lft);
216 return Map(_root->_rgt);
220 Map insert(
const K& x,
const V& v)
const
225 const K& y = rootKey();
226 const V& yv = rootValue();
227 Color c = rootColor();
229 if (rootColor() == B)
232 return balance(left().insert(x, v), y, yv, right());
234 return balance(left(), y, yv, right().insert(x, v));
236 return Map(c, left(), y, v, right());
241 return Map(c, left().insert(x, v), y, yv, right());
243 return Map(c, left(), y, yv, right().insert(x, v));
245 return Map(c, left(), y, v, right());
250 static Map balance(
const Map& lft,
const K& x,
const V& v,
const Map& rgt)
252 if (lft.doubledLeft())
258 Map(B, lft.right(), x, v, rgt));
259 else if (lft.doubledRight())
263 B, lft.left(), lft.rootKey(), lft.rootValue(), lft.right().left()),
264 lft.right().rootKey(),
265 lft.right().rootValue(),
266 Map(B, lft.right().right(), x, v, rgt));
267 else if (rgt.doubledLeft())
270 Map(B, lft, x, v, rgt.left().left()),
271 rgt.left().rootKey(),
272 rgt.left().rootValue(),
279 else if (rgt.doubledRight())
282 Map(B, lft, x, v, rgt.left()),
285 rgt.right().paint(B));
287 return Map(B, lft, x, v, rgt);
290 bool doubledLeft()
const
292 return !
empty() && rootColor() == R && !left().
empty() &&
293 left().rootColor() == R;
296 bool doubledRight()
const
298 return !
empty() && rootColor() == R && !right().
empty() &&
299 right().rootColor() == R;
302 Map paint(Color c)
const
304 return Map(c, left(), rootKey(), rootValue(), right());
307 Map rotateRight()
const
310 auto y =
Map(rootColor(), x.right(), rootKey(), rootValue(), right());
311 return Map(x.rootColor(), x.left(), x.rootKey(), x.rootValue(), y);
314 Map rotateLeft()
const
317 auto x =
Map(rootColor(), left(), rootKey(), rootValue(), y.left());
318 return Map(y.rootColor(), x, y.rootKey(), y.rootValue(), y.right());
324 std::pair<Map, bool> fixDoubleBlackLeft()
const
326 auto sibling = right();
328 auto root =
Map(*
this);
330 if (sibling.rootColor() == R)
334 R, root.left(), root.rootKey(), root.rootValue(), sibling.paint(B));
336 root = root.rotateLeft();
339 auto fixedLeft = root.left().fixDoubleBlackLeft();
346 if (!fixedLeft.second)
349 return std::make_pair(root,
false);
353 sibling = root.right();
356 auto doubleBlack =
false;
357 if (sibling.left().rootColor() == B && sibling.right().rootColor() == B)
362 sibling = sibling.paint(R);
364 doubleBlack = root.rootColor() == B;
365 root =
Map(B, root.left(), root.rootKey(), root.rootValue(), sibling);
369 if (sibling.right().rootColor() == B)
373 auto siblingLeft = sibling.left().paint(B);
380 sibling = sibling.rotateRight();
389 auto recoloredSibling =
Map(
394 sibling.right().paint(B));
396 B, root.left(), root.rootKey(), root.rootValue(), recoloredSibling);
397 root = root.rotateLeft();
400 return std::make_pair(root, doubleBlack);
403 std::pair<Map, bool> fixDoubleBlackRight()
const
405 auto sibling = left();
407 auto root =
Map(*
this);
409 if (sibling.rootColor() == R)
413 R, sibling.paint(B), root.rootKey(), root.rootValue(), root.right());
415 root = root.rotateRight();
418 auto fixedRight = root.right().fixDoubleBlackRight();
425 if (!fixedRight.second)
428 return std::make_pair(root,
false);
432 sibling = root.left();
435 auto doubleBlack =
false;
436 if (sibling.left().rootColor() == B && sibling.right().rootColor() == B)
441 sibling = sibling.paint(R);
443 doubleBlack = root.rootColor() == B;
444 root =
Map(B, sibling, root.rootKey(), root.rootValue(), root.right());
448 if (sibling.left().rootColor() == B)
452 auto siblingRight = sibling.right().paint(B);
459 sibling = sibling.rotateLeft();
468 auto recoloredSibling =
Map(
470 sibling.left().paint(B),
475 B, recoloredSibling, root.rootKey(), root.rootValue(), root.right());
476 root = root.rotateRight();
479 return std::make_pair(root, doubleBlack);
485 std::pair<Map, bool> _remove(
const K& key)
const
491 return std::make_pair(
Map(),
false);
494 const K& rootk = rootKey();
499 auto left_without = left()._remove(key);
502 Map(rootColor(), left_without.first, rootKey(), rootValue(), right());
503 if (left_without.second)
506 return newMap.fixDoubleBlackLeft();
509 return std::make_pair(newMap,
false);
511 else if (rootk < key)
514 auto right_without = right()._remove(key);
516 Map(rootColor(), left(), rootKey(), rootValue(), right_without.first);
517 if (right_without.second)
519 return newMap.fixDoubleBlackRight();
521 return std::make_pair(newMap,
false);
523 else if (key == rootk)
529 auto doubleBlack = rootColor() == B;
530 return std::make_pair(
Map(), doubleBlack);
532 else if (left().
empty())
543 assert(r.left().empty());
544 assert(r.right().empty());
545 assert(r.rootColor() == R);
546 return std::make_pair(r.paint(B),
false);
548 else if (right().
empty())
552 assert(l.left().empty());
553 assert(l.right().empty());
554 assert(l.rootColor() == R);
555 return std::make_pair(l.paint(B),
false);
561 auto successor = right().minimum();
562 auto right_without = right()._remove(successor.first);
568 right_without.first);
569 if (right_without.second)
571 return newMap.fixDoubleBlackRight();
573 return std::make_pair(newMap,
false);
579 return std::make_pair(
Map(*
this),
false);
584 std::pair<K, V> minimum()
const
590 return std::make_pair(rootKey(), rootValue());
594 return left().minimum();
602 size_t totalBlackCount = 0;
603 _check(0, totalBlackCount);
609 std::string to_str()
const
611 auto ss = std::stringstream();
617 auto color = rootColor() == B ?
"B" :
"R";
618 ss <<
"(" << color <<
" " << left().to_str() << right().to_str() <<
")";
624 void _check(
size_t blackCount,
size_t& totalBlackCount)
const
628 totalBlackCount = blackCount + 1;
632 if (rootColor() == R)
634 if (!left().
empty() && left().rootColor() == R)
636 throw std::logic_error(
"rb::Map::check(): Double red node found");
638 if (!right().
empty() && right().rootColor() == R)
640 throw std::logic_error(
"rb::Map::check(): Double red node found");
643 size_t leftBlackCount = 0;
644 size_t rightBlackCount = 0;
645 left()._check(blackCount + (rootColor() == B ? 1 : 0), leftBlackCount);
646 right()._check(blackCount + (rootColor() == B ? 1 : 0), rightBlackCount);
648 if (leftBlackCount != rightBlackCount)
650 std::cout << to_str() << std::endl;
651 throw std::logic_error(fmt::format(
652 "rb::Map::check(): black counts didn't match between left and right "
658 totalBlackCount = leftBlackCount + (rootColor() == B ? 1 : 0);