Path: blob/main/contrib/llvm-project/libc/src/__support/freetrie.cpp
213766 views
//===-- Implementation for freetrie ---------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "freetrie.h"910namespace LIBC_NAMESPACE_DECL {1112void FreeTrie::remove(Node *node) {13LIBC_ASSERT(!empty() && "cannot remove from empty trie");14FreeList list = node;15list.pop();16Node *new_node = static_cast<Node *>(list.begin());17if (!new_node) {18// The freelist is empty. Replace the subtrie root with an arbitrary leaf.19// This is legal because there is no relationship between the size of the20// root and its children.21Node *leaf = node;22while (leaf->lower || leaf->upper)23leaf = leaf->lower ? leaf->lower : leaf->upper;24if (leaf == node) {25// If the root is a leaf, then removing it empties the subtrie.26replace_node(node, nullptr);27return;28}2930replace_node(leaf, nullptr);31new_node = leaf;32}3334if (!is_head(node))35return;3637// Copy the trie links to the new head.38new_node->lower = node->lower;39new_node->upper = node->upper;40new_node->parent = node->parent;41replace_node(node, new_node);42}4344void FreeTrie::replace_node(Node *node, Node *new_node) {45LIBC_ASSERT(is_head(node) && "only head nodes contain trie links");4647if (node->parent) {48Node *&parent_child =49node->parent->lower == node ? node->parent->lower : node->parent->upper;50LIBC_ASSERT(parent_child == node &&51"no reference to child node found in parent");52parent_child = new_node;53} else {54LIBC_ASSERT(root == node && "non-root node had no parent");55root = new_node;56}57if (node->lower)58node->lower->parent = new_node;59if (node->upper)60node->upper->parent = new_node;61}6263} // namespace LIBC_NAMESPACE_DECL646566