// 스택을 정리한다. protected TrieNode SaveStack(TrieKey key, Stack <TrieNode> stack) { TrieNode root = null; TrieKey k = key.Clone(); while (stack.Count > 0) { TrieNode node = stack.Pop(); if (node.Type == NodeType.ValueNode) { k.Pop(node.Key.Length); } else if (node.Type == NodeType.ShortNode) { k.Pop(node.Key.Length); if (null != root) { node.Next = root; } } else if (node.Type == NodeType.FullNode) { if (null != root) { Guard.Assert(!k.Empty); node.SetChild(k.Pop(), root); } } // 노드 RLP 인코딩 root = node.EncodeRLP(); } return(root); }
// 루트 부터 key에 해당하는 경로를 탐색하여 // 일치하는 노드, 잔여 경로, 노드 스택(경로에 해당하는) 을 구한다. protected (TrieNode found, TrieKey keyRemainder, Stack <TrieNode> stack) FindNode(TrieNode root, TrieKey key) { if (ReferenceEquals(root, null)) { throw new ArgumentNullException(nameof(root)); } if (ReferenceEquals(key, null) || key.Empty) { throw new ArgumentNullException(nameof(key)); } // 노드 경로 스택 Stack <TrieNode> stack = new Stack <TrieNode>(); // 노드와 검색 경로 TrieNode node = root; TrieKey keyRemainder = key.Clone(); while (node != null && node.Type != NodeType.EmptyNode) { // 노드 스택에 노드 추가 stack.Push(node); // 현재 노드가 브랜치 노드이면 if (node.Type == NodeType.FullNode) { // 브랜치 노드에서 경로가 종료되면 탐색 종료 if (keyRemainder.Empty) { return(node, TrieKey.EmptyKey, stack); } // 경로에 해당하는 자식 노드가 없으면 탐색 종료 Nibble radix = keyRemainder[0]; TrieNode child = node.GetChild(radix); if (child == null) { return(null, keyRemainder, stack); } // 자식 노드로 탐색 계속 진행 node = child; keyRemainder.PopFront(); continue; } // 현재 노드가 익스텐션 노드이면 if (node.Type == NodeType.ShortNode) { // 노드 키 ( 항상 키가 존재해야 한다 ) TrieKey k = node.Key; Guard.Assert(!k.Empty); // 익스텐션 키가 일치하지 않으면 탐색 종료 int matchingLength = keyRemainder.Compare(k); if (matchingLength != k.Length) { return(null, keyRemainder, stack); } // 익스텐션 노드의 자식 노드로 계속 탐색 진행 //keyRemainder.PopFront(k.Length); keyRemainder = keyRemainder.Skip(k.Length); node = node.Next; continue; } // 리프 노드 return(keyRemainder == node.Key ? (node, TrieKey.EmptyKey, stack) : (null, keyRemainder, stack)); } throw new Exception("wtf!"); }