1*71db0c75SAndroid Build Coastguard Worker //===-- Implementation for freetrie ---------------------------------------===// 2*71db0c75SAndroid Build Coastguard Worker // 3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*71db0c75SAndroid Build Coastguard Worker // 7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*71db0c75SAndroid Build Coastguard Worker 9*71db0c75SAndroid Build Coastguard Worker #include "freetrie.h" 10*71db0c75SAndroid Build Coastguard Worker 11*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL { 12*71db0c75SAndroid Build Coastguard Worker remove(Node * node)13*71db0c75SAndroid Build Coastguard Workervoid FreeTrie::remove(Node *node) { 14*71db0c75SAndroid Build Coastguard Worker LIBC_ASSERT(!empty() && "cannot remove from empty trie"); 15*71db0c75SAndroid Build Coastguard Worker FreeList list = node; 16*71db0c75SAndroid Build Coastguard Worker list.pop(); 17*71db0c75SAndroid Build Coastguard Worker Node *new_node = static_cast<Node *>(list.begin()); 18*71db0c75SAndroid Build Coastguard Worker if (!new_node) { 19*71db0c75SAndroid Build Coastguard Worker // The freelist is empty. Replace the subtrie root with an arbitrary leaf. 20*71db0c75SAndroid Build Coastguard Worker // This is legal because there is no relationship between the size of the 21*71db0c75SAndroid Build Coastguard Worker // root and its children. 22*71db0c75SAndroid Build Coastguard Worker Node *leaf = node; 23*71db0c75SAndroid Build Coastguard Worker while (leaf->lower || leaf->upper) 24*71db0c75SAndroid Build Coastguard Worker leaf = leaf->lower ? leaf->lower : leaf->upper; 25*71db0c75SAndroid Build Coastguard Worker if (leaf == node) { 26*71db0c75SAndroid Build Coastguard Worker // If the root is a leaf, then removing it empties the subtrie. 27*71db0c75SAndroid Build Coastguard Worker replace_node(node, nullptr); 28*71db0c75SAndroid Build Coastguard Worker return; 29*71db0c75SAndroid Build Coastguard Worker } 30*71db0c75SAndroid Build Coastguard Worker 31*71db0c75SAndroid Build Coastguard Worker replace_node(leaf, nullptr); 32*71db0c75SAndroid Build Coastguard Worker new_node = leaf; 33*71db0c75SAndroid Build Coastguard Worker } 34*71db0c75SAndroid Build Coastguard Worker 35*71db0c75SAndroid Build Coastguard Worker if (!is_head(node)) 36*71db0c75SAndroid Build Coastguard Worker return; 37*71db0c75SAndroid Build Coastguard Worker 38*71db0c75SAndroid Build Coastguard Worker // Copy the trie links to the new head. 39*71db0c75SAndroid Build Coastguard Worker new_node->lower = node->lower; 40*71db0c75SAndroid Build Coastguard Worker new_node->upper = node->upper; 41*71db0c75SAndroid Build Coastguard Worker new_node->parent = node->parent; 42*71db0c75SAndroid Build Coastguard Worker replace_node(node, new_node); 43*71db0c75SAndroid Build Coastguard Worker } 44*71db0c75SAndroid Build Coastguard Worker replace_node(Node * node,Node * new_node)45*71db0c75SAndroid Build Coastguard Workervoid FreeTrie::replace_node(Node *node, Node *new_node) { 46*71db0c75SAndroid Build Coastguard Worker LIBC_ASSERT(is_head(node) && "only head nodes contain trie links"); 47*71db0c75SAndroid Build Coastguard Worker 48*71db0c75SAndroid Build Coastguard Worker if (node->parent) { 49*71db0c75SAndroid Build Coastguard Worker Node *&parent_child = 50*71db0c75SAndroid Build Coastguard Worker node->parent->lower == node ? node->parent->lower : node->parent->upper; 51*71db0c75SAndroid Build Coastguard Worker LIBC_ASSERT(parent_child == node && 52*71db0c75SAndroid Build Coastguard Worker "no reference to child node found in parent"); 53*71db0c75SAndroid Build Coastguard Worker parent_child = new_node; 54*71db0c75SAndroid Build Coastguard Worker } else { 55*71db0c75SAndroid Build Coastguard Worker LIBC_ASSERT(root == node && "non-root node had no parent"); 56*71db0c75SAndroid Build Coastguard Worker root = new_node; 57*71db0c75SAndroid Build Coastguard Worker } 58*71db0c75SAndroid Build Coastguard Worker if (node->lower) 59*71db0c75SAndroid Build Coastguard Worker node->lower->parent = new_node; 60*71db0c75SAndroid Build Coastguard Worker if (node->upper) 61*71db0c75SAndroid Build Coastguard Worker node->upper->parent = new_node; 62*71db0c75SAndroid Build Coastguard Worker } 63*71db0c75SAndroid Build Coastguard Worker 64*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL 65