public ZipResult ZipWith(StringPartition other) { var splitIndex = 0; using (var thisEnumerator = GetEnumerator()) using (var otherEnumerator = other.GetEnumerator()) { while (thisEnumerator.MoveNext() && otherEnumerator.MoveNext()) { if (thisEnumerator.Current != otherEnumerator.Current) { break; } splitIndex++; } } var thisSplitted = Split(splitIndex); var otherSplitted = other.Split(splitIndex); var commonHead = thisSplitted.Head; var restThis = thisSplitted.Rest; var restOther = otherSplitted.Rest; return(new ZipResult(commonHead, restThis, restOther)); }
protected PatriciaTrieNode(StringPartition key, Queue <TValue> values, Dictionary <char, PatriciaTrieNode <TValue> > children) { mValues = values; mKey = key; mChildren = children; }
public SplitResult Split(int splitAt) { var head = new StringPartition(mOrigin, mStartIndex, splitAt); var rest = new StringPartition(mOrigin, mStartIndex + splitAt, Length - splitAt); return(new SplitResult(head, rest)); }
public bool StartsWith(StringPartition other) { if (Length < other.Length) { return(false); } return(!other.Where((t, i) => this[i] != t).Any()); }
private void SplitOne(ZipResult zipResult, TValue value) { var leftChild = new PatriciaTrieNode <TValue>(zipResult.ThisRest, mValues, mChildren); mChildren = new Dictionary <char, PatriciaTrieNode <TValue> >(); mValues = new Queue <TValue>(); AddValue(value); mKey = zipResult.CommonHead; mChildren.Add(zipResult.ThisRest[0], leftChild); }
protected void GetOrCreateChild(StringPartition key, TValue value) { if (!mChildren.TryGetValue(key[0], out var child)) { child = new PatriciaTrieNode <TValue>(key, value); mChildren.Add(key[0], child); } else { child.Add(key, value); } }
protected override TrieNodeBase <TValue> GetChildOrNull(string query, int position) { if (query == null) { throw new ArgumentNullException("query"); } if (!mChildren.TryGetValue(query[position], out var child)) { return(null); } var queryPartition = new StringPartition(query, position, child.mKey.Length); return(child.mKey.StartsWith(queryPartition) ? child : null); }
private void SplitTwo(ZipResult zipResult, TValue value) { var leftChild = new PatriciaTrieNode <TValue>(zipResult.ThisRest, mValues, mChildren); var rightChild = new PatriciaTrieNode <TValue>(zipResult.OtherRest, value); mChildren = new Dictionary <char, PatriciaTrieNode <TValue> >(); mValues = new Queue <TValue>(); mKey = zipResult.CommonHead; char leftKey = zipResult.ThisRest[0]; mChildren.Add(leftKey, leftChild); char rightKey = zipResult.OtherRest[0]; mChildren.Add(rightKey, rightChild); }
internal virtual void Add(StringPartition keyRest, TValue value) { var zipResult = mKey.ZipWith(keyRest); switch (zipResult.MatchKind) { case MatchKind.ExactMatch: AddValue(value); break; case MatchKind.IsContained: GetOrCreateChild(zipResult.OtherRest, value); break; case MatchKind.Contains: SplitOne(zipResult, value); break; case MatchKind.Partial: SplitTwo(zipResult, value); break; } }
protected PatriciaTrieNode(StringPartition key, TValue value) : this(key, new Queue <TValue>(new[] { value }), new Dictionary <char, PatriciaTrieNode <TValue> >()) { }
public bool Equals(StringPartition other) { return(string.Equals(mOrigin, other.mOrigin) && Length == other.Length && mStartIndex == other.mStartIndex); }
internal override void Add(StringPartition keyRest, TValue value) { GetOrCreateChild(keyRest, value); }
public ZipResult(StringPartition commonHead, StringPartition thisRest, StringPartition otherRest) { CommonHead = commonHead; ThisRest = thisRest; OtherRest = otherRest; }