/// <summary> /// Adds/Updates an entry in the tree /// </summary> /// <param name="ID">Hash is the Full hash for the value (32 bytes)</param> /// <param name="value"></param> /// <returns>True if added. False if updated.</returns> public bool AddUpdate(Hash ID, LeafDataType value) { if(Values.ContainsKey(ID)) { Values[ID] = value; return false; } else { Values.Add(ID, value); return true; } }
public LeafDataType[] GetAllItems() { LeafDataType[] listItems = new LeafDataType[Values.Count]; int elems = 0; foreach (KeyValuePair<Hash, LeafDataType> val in Values) { listItems[elems++] = val.Value; } if (elems != Values.Count) new InvalidOperationException("Addition or removal during fetch, thread-unsafe-operation"); return listItems; }
/// <summary> /// Gets the element at the position specified by the ID. /// </summary> /// <param name="ID"></param> /// <param name="Leaf"></param> /// <returns></returns> public TraverseResult GetNodeData(Hash ID, out LeafDataType Leaf) { ListTreeLeafNode LN; TraverseResult tr = TraverseToLeaf(ID, out LN); if (tr == TraverseResult.Success) { if (LN.ContainsElement(ID)) { Leaf = LN[ID]; return TraverseResult.Success; } else { Leaf = default(LeafDataType); return TraverseResult.ElementDoesNotExistInLeaf; } } else { Leaf = default(LeafDataType); return tr; } }
/// <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 }
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 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; }
public static long CalculateTotalMoney(LeafDataType[] ais) { long _money = 0; foreach (LeafDataType ai in ais) { _money += ((AccountInfo)ai).money; } return _money; }