bool _innerGetNodeByPath(IList <TKey> path, int endIdx, out DTree <TKey, TValue> node) { TKey key; DTree <TKey, TValue> stree = this; for (int i = 0; i < endIdx; i++) { key = path[i]; if (!stree.TryGetChild(key, out stree)) { node = null; return(false); } } key = path[endIdx]; if (!stree.TryGetChild(key, out stree)) { node = null; return(false); } else { node = stree; return(true); } }
public static void WriteDictionaryTree <TKey, TValue>(this BitStream stream, DTree <TKey, TValue> tree, Action <Stream, KeyValuePair <TKey, TValue> > writeValue) { var ie = tree.GetBreadthFirstEnumerator(); while (ie.MoveNext()) { var node = ie.Current; if (node == null) { stream.WriteBit(true); } else { stream.WriteBit(false); var isValueNull = (node.Value.Key == null && node.Value.Value == null); stream.WriteBit(isValueNull); if (node.Children == null) { stream.WriteDeltaCode(0); } else { stream.WriteDeltaCode(node.Children.Count); } if (!isValueNull) { writeValue(stream, node.Value); } } } }
public static void WriteDictionaryTree <TKey, TValue>(this Stream stream, DTree <TKey, TValue> tree, Action <Stream, KeyValuePair <TKey, TValue> > writeValue) { var ie = tree.GetBreadthFirstEnumerator(); while (ie.MoveNext()) { var node = ie.Current; if (node == null) { stream.WriteByte(1); } else { byte tag = 0; var isValueNull = (node.Value.Key == null && node.Value.Value == null); tag = tag.SetBit(1, isValueNull); stream.WriteByte(tag); if (node.Children == null) { stream.WriteInt32(0); } else { stream.WriteInt32(node.Children.Count); } if (!isValueNull) { writeValue(stream, node.Value); } } } }
/// <summary> /// Adds a child node to this tree node. /// </summary> /// <param name="node">The child node to add.</param> public void AddChild(DTree <TKey, TValue> node) { if (_children == null) { _children = new HybridDictionary <TKey, DTree <TKey, TValue> >(); } node.Parent = this; _children.Add(node.Key, node); }
/// <summary> /// Gets the child node associated with the specified key. /// </summary> /// <param name="childKey">The key of the child node.</param> /// <param name="child">Returns the child node associated with the specified key, if the key is found; otherwise, <c>null</c>.</param> /// <returns></returns> public bool TryGetChild(TKey childKey, out DTree <TKey, TValue> child) { if (_children.IsNullOrEmpty()) { child = null; return(false); } else { return(_children.TryGetValue(childKey, out child)); } }
public static DTree <string, TValue> AddByPath <TValue>(this DTree <string, TValue> tree, string[] path, TValue value, Action <DTree <string, TValue> > nodeAdded = null) { var node = tree.TryAdd(path, value, nodeAdded); if (node == null) { throw new InvalidOperationException(GenericResources.ERR_Common_PathAlreadyExist); } else { return(node); } }
/// <summary> /// Determines whether the specified path exists in this tree. /// </summary> /// <param name="path">A path consists of several keys.</param> /// <returns><c>true</c> if the specified path exists in the current tree; otherwise, <c>false</c>.</returns> public bool ContainsPath(IList <TKey> path) { TKey key; DTree <TKey, TValue> stree = this; for (int i = 0; i < path.Count; i++) { key = path[i]; if (!stree.TryGetChild(key, out stree)) { return(false); } } return(stree != null); }
/// <summary> /// Adds a new child node with the specified key/value pair to this tree node. /// </summary> /// <param name="key">The key of the child node to add.</param> /// <param name="value">The value of the child node to add.</param> /// <returns> /// The added new child node. /// </returns> public DTree <TKey, TValue> AddChild(TKey key, TValue value) { if (_children == null) { _children = new HybridDictionary <TKey, DTree <TKey, TValue> >(); } if (_children.ContainsKey(key)) { return(null); } else { var nt = new DTree <TKey, TValue>(key, value); nt.Parent = this; _children.Add(key, nt); return(nt); } }
/// <summary> /// Adds a value together with the path it is to associate to this tree. /// </summary> /// <param name="path">A path consists of several keys.</param> /// <param name="value">The value associated with the specified path.</param> /// <param name="nodeCreated">A function called everytime a new node is created.</param> /// <returns>A node that stores the value associated with the specified path, if the path and value are both successfully added; /// <c>null</c> if a value is already associated with the path. /// This node is also the last node along the path.</returns> public DTree <TKey, TValue> TryAdd(IList <TKey> path, TValue value, Action <DTree <TKey, TValue> > nodeCreated = null) { try { TKey key; DTree <TKey, TValue> stree = this; DTree <TKey, TValue> ttree; var len = path.Count - 1; for (int i = 0; i < len; i++) { key = path[i]; if (!stree.TryGetChild(key, out ttree)) { stree = stree.AddChild(key, default(TValue)); if (nodeCreated != null) { nodeCreated(stree); } } else { stree = ttree; } } key = path[len]; if (!stree.TryGetChild(key, out ttree)) { return(stree.AddChild(key, value)); } else { return(null); } } catch { return(null); } }
/// <summary> /// Gets the descendant node of this tree associated with the specified path. The path should already exist in this tree. /// </summary> /// <param name="path">A path consists of several keys.</param> /// <param name="node">Returns the descendant node associated with the specified path, if the path exists in this tree; otherwise, <c>null</c>.</param> /// <returns><c>true</c> if the specified path exists in this tree and the descendant node associated with that path is returned.</returns> public bool TryGetNode(IList <TKey> path, out DTree <TKey, TValue> node) { return(_innerGetNodeByPath(path, path.Count - 1, out node)); }
/// <summary> /// Removes the specified child node from this tree node. /// </summary> /// <param name="node">The child node to remove.</param> /// <returns> /// <c>true</c> if the child node is successfully removed; otherwise, <c>false</c>. /// </returns> public bool RemoveChild(DTree <TKey, TValue> node) { return(RemoveChild(node._key)); }
public static DTree <TKey, TValue> ReadDictionaryTree <TKey, TValue>(this Stream stream, Func <Stream, KeyValuePair <TKey, TValue> > readValue, Action <DTree <TKey, TValue> > nodeCreated = null) { var q = new Queue <DTree <TKey, TValue> >(); DTree <TKey, TValue> root; var tag = (byte)stream.ReadByte(); bool isNull = tag.GetBit(0); bool isValueNull = tag.GetBit(1); if (isNull) { return(null); } else { var len = stream.ReadInt32(); if (!isValueNull) { var kp = readValue(stream); root = new DTree <TKey, TValue>(kp.Key, kp.Value); } else { root = new DTree <TKey, TValue>(); } if (nodeCreated != null) { nodeCreated(root); } for (int i = 0; i < len; i++) { q.Enqueue(root); } } while (q.Count > 0) { var parent = q.Dequeue(); tag = (byte)stream.ReadByte(); isNull = tag.GetBit(0); isValueNull = tag.GetBit(1); if (isNull) { throw new InvalidOperationException(); } else { var len = stream.ReadInt32(); DTree <TKey, TValue> newNode; if (!isValueNull) { var kp = readValue(stream); newNode = parent.AddChild(kp.Key, kp.Value); if (newNode == null) { throw new InvalidDataException(); } if (nodeCreated != null && newNode != null) { nodeCreated(newNode); } } else { throw new InvalidOperationException(); } for (int i = 0; i < len; i++) { q.Enqueue(newNode); } } } return(root); }