public TrieItem(Bits prefix, bool hasValue, T value, TrieItem <T> @true, TrieItem <T> @false) { Prefix = prefix; HasValue = hasValue; Value = value; True = @true; False = @false; }
private void AddToChild(ref TrieItem <T> child, IEnumerable <bool> enumerable, T value) { var bits = new Bits(enumerable); if (child == null) { child = new TrieItem <T>(bits, value); } else { var commonBits = child.Prefix.Common(bits); if (child.Prefix.Count == commonBits.Count) { if (child.Prefix.Count == bits.Count) { // Set value, if not already set if (child.HasValue) { throw new ArgumentException("Duplicate key"); } var oldChild = child; child = new TrieItem <T>(oldChild.Prefix, true, value, oldChild.True, oldChild.False); } else { child.AddItem(bits, value); } } else { //split subtrie along the common prefix var oldChild = child; if (commonBits.Count == bits.Count) { child = new TrieItem <T>(commonBits, value); } else { child = new TrieItem <T>(commonBits); child.AddItem(bits, value); } child.MakeGrandchild(oldChild); } } }
private void MakeGrandchild(TrieItem <T> oldChild) { var discriminator = oldChild.Prefix.Skip(Prefix.Count).First(); var grandchild = new TrieItem <T>(oldChild.Prefix.Skip(Prefix.Count + 1), oldChild.HasValue, oldChild.Value, oldChild.True, oldChild.False); if (discriminator) { if (True != null) { throw new InvalidOperationException("Child 1 already set"); } True = grandchild; } else { if (False != null) { throw new InvalidOperationException("Child 0 already set"); } False = grandchild; } }