public void Add(LeafDataType ldt) { Values.Add(ldt.GetID(), ldt); }
/// <summary> /// Adds an element to the tree. If the element exists, update it. /// </summary> /// <param name="Value">The Value to be added</param> /// <returns></returns> public TreeResponseType AddUpdate(LeafDataType Value) { bool Good = false; bool Add = true; Hash ID = Value.GetID(); ListTreeNode TempRoot = Root; Stack<ListTreeNode> PathStack = new Stack<ListTreeNode>(); List<byte> addressNibbleList = new List<byte>(); PathStack.Push(TempRoot); int LeafDepth = Constants.HashTree_NodeListDepth; //ID.Hex.Length << 1; // Multiply by 2 for (int i = 0; i < LeafDepth; i++) { byte Nibble = ID.GetNibble(i); addressNibbleList.Add(Nibble); // Insert new node if ((TempRoot.Children[Nibble] == null) && (i < (LeafDepth - 1))) { TempRoot.Children[Nibble] = new ListTreeNode(); TempRoot.Children[Nibble].addressNibbles = new Hash(addressNibbleList.ToArray()); _TraversedNodes++; } // Make child as curent if ((i < (LeafDepth - 1))) { TempRoot = TempRoot.Children[Nibble]; PathStack.Push(TempRoot); } // Insert leaf if (i == (LeafDepth - 1)) { // Add new leaf node if (TempRoot.Children[Nibble] == null) { Dictionary<Hash, LeafDataType> _Values = new Dictionary<Hash, LeafDataType>(); _Values.Add(Value.GetID(), Value); TempRoot.Children[Nibble] = new ListTreeLeafNode(_Values); TempRoot.Children[Nibble].addressNibbles = new Hash(addressNibbleList.ToArray()); _TraversedNodes++; Add = true; Good = true; } // Add to current leaf node else if (TempRoot.Children[Nibble].GetType() == typeof(ListTreeLeafNode)) { var ltln = (ListTreeLeafNode)TempRoot.Children[Nibble]; Add = ltln.AddUpdate(Value.GetID(), Value); Good = true; } else { throw new Exception("Bad Mess !!!"); } } } /// Traceback. bool LeafDone = false; while (PathStack.Count > 0) { ListTreeNode val = PathStack.Pop(); Hash NodeHash = null; long entityCount = 0; List<byte> _tempHash = new List<byte>(); if (!LeafDone) { // Do the hashing for the leaf. for (int i = 0; i < 16; i++) { if (val.Children[i] != null) { var ai = (ListTreeLeafNode)val.Children[i]; entityCount += ai.Count; Hash hsh = ai.GetHash(); _tempHash.AddRange(hsh.Hex); //DisplayUtils.Display("CH : - " + i.ToString("X") + " : " + HexUtil.ToString(hsh.Hex)); } } NodeHash = new Hash((new SHA512Cng()).ComputeHash(_tempHash.ToArray()).Take(32).ToArray()); LeafDone = true; } else { // Perform hashing for node. for (int i = 0; i < 16; i++) { if (val.Children[i] != null) { var ai = (ListTreeNode)val.Children[i]; entityCount += ai.LeafCount; _tempHash.AddRange(ai.Hash.Hex); //DisplayUtils.Display("- " + i.ToString("X") + " : " + HexUtil.ToString(ai.Hash.Hex)); } } NodeHash = new Hash((new SHA512Cng()).ComputeHash(_tempHash.ToArray()).Take(32).ToArray()); } val.SetLeafCount(entityCount); val.SetHash(NodeHash); } return Good ? //IS Good (Add ? TreeResponseType.Added : TreeResponseType.Updated) : // YES: Added / Updated TreeResponseType.Failed; // NO }
/// <summary> /// Adds an element to the tree. If the element exists, update it. /// </summary> /// <param name="Value">The Value to be added</param> /// <returns></returns> public bool AddUpdate(LeafDataType Value) { bool Good = false; Hash ID = Value.GetID(); TreeNode<LeafDataType> TempRoot = Root; Stack<TreeNode<LeafDataType>> PathStack = new Stack<TreeNode<LeafDataType>>(); PathStack.Push(TempRoot); int HLEN = ID.Hex.Length << 1; // Multiply by 2 for (int i = 0; i < HLEN; i++) { byte Nibble = ID.GetNibble(i); // Insert new node if ((TempRoot.Children[Nibble] == null) && (i < (HLEN - 1))) { TempRoot.Children[Nibble] = new TreeNode<LeafDataType>(); _TotalNodes++; } // Make child as curent if ((i < (HLEN - 1))) { TempRoot = TempRoot.Children[Nibble]; PathStack.Push(TempRoot); } // Insert leaf if (i == (HLEN - 1)) { if (TempRoot.Children[Nibble] == null) { TempRoot.Children[Nibble] = new TreeLeafNode<LeafDataType>(ID, Value); _TotalNodes++; // DisplayUtils.Display("Node Added: " + HexUtil.ToString(ID.Hex)); Good = true; } else if (TempRoot.Children[Nibble].GetType() == typeof(TreeLeafNode<LeafDataType>)) { if (TempRoot.Children[Nibble].ID == ID) { ((TreeLeafNode<LeafDataType>)TempRoot.Children[Nibble]).Value = Value; Good = true; } else { throw new Exception("Node ID Mismatch, Bad Mess !!!"); } } else { throw new Exception("Node Already Exists"); } } } /// Traceback. bool LeafDone = false; while (PathStack.Count > 0) { TreeNode<LeafDataType> val = PathStack.Pop(); Hash NodeHash = null; if (!LeafDone) { List<byte> hashDataArray = new List<byte>(); for (int i = 0; i < 16; i++) { if (val.Children[i] != null) { var ai = (TreeLeafNode<LeafDataType>)val.Children[i]; Hash hsh = ai.Value.GetHash(); hashDataArray.AddRange(hsh.Hex); // DisplayUtils.Display("CH : - " + i.ToString("X") + " : " + HexUtil.ToString(hsh.Hex)); } } NodeHash = new Hash((new SHA512Managed()).ComputeHash(hashDataArray.ToArray()).Take(32).ToArray()); LeafDone = true; } else { List<byte> hashDataArray = new List<byte>(); for (int i = 0; i < 16; i++) { if (val.Children[i] != null) { var ai = (TreeNode<LeafDataType>)val.Children[i]; hashDataArray.AddRange(ai.ID.Hex); // DisplayUtils.Display("- " + i.ToString("X") + " : " + HexUtil.ToString(ai.ID.Hex) ); } } NodeHash = new Hash((new SHA512Managed()).ComputeHash(hashDataArray.ToArray()).Take(32).ToArray()); } val.ID = NodeHash; } return Good; }