private static bool AddNonDuplicateExtracted(ref AVLNode <TKey, TValue>?node, TKey key, TValue value, IComparer <TKey> comparer, AVLNode <TKey, TValue>?created) { // Ok, it has for node only if (node == null) { if (created == null) { created = new AVLNode <TKey, TValue>(key, value); } var found = Interlocked.CompareExchange(ref node, created, null); if (found == null) { return(true); } node = found; } var compare = comparer.Compare(key, node.Key); if (compare == 0) { return(false); } try { return(compare < 0 ? AddNonDuplicateExtracted(ref node._left, key, value, comparer, created) : AddNonDuplicateExtracted(ref node._right, key, value, comparer, created)); } finally { MakeBalanced(ref node); } }
internal static void Add(ref AVLNode <TKey, TValue>?node, TKey key, TValue value, IComparer <TKey> comparer) { var created = new AVLNode <TKey, TValue>(key, value); AddExtracted(ref node, key, comparer, created); }
internal static void Bound(AVLNode <TKey, TValue> node, TKey key, IComparer <TKey> comparer, out AVLNode <TKey, TValue> lower, out AVLNode <TKey, TValue> upper) { lower = null; upper = null; while (node != null) { var compare = comparer.Compare(key, node.Key); if (compare <= 0) { upper = node; } if (compare >= 0) { lower = node; } if (compare == 0) { break; } node = compare < 0 ? node._left : node._right; } }
internal static AVLNode <TKey, TValue>?RemoveNearestRight(ref AVLNode <TKey, TValue>?node, TKey key, IComparer <TKey> comparer) { AVLNode <TKey, TValue>?result = null; return(RemoveNearestRightExtracted(ref node, ref result, key, comparer)); }
private static bool AddNonDuplicateExtracted(ref AVLNode <TKey, TValue>?node, TKey key, TValue value, IComparer <TKey> comparer, AVLNode <TKey, TValue>?created) { #if DEBUG // NOTICE this method has no null check in the public build as an optimization, this is just to appease the dragons if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } #endif // Ok, it has for node only if (node == null) { if (created == null) { created = new AVLNode <TKey, TValue>(key, value); } var found = Interlocked.CompareExchange(ref node, created, null); if (found == null) { return(true); } node = found; } var compare = comparer.Compare(key, node.Key); if (compare == 0) { return(false); } try { return(compare < 0 ? AddNonDuplicateExtracted(ref node._left, key, value, comparer, created) : AddNonDuplicateExtracted(ref node._right, key, value, comparer, created)); } finally { MakeBalanced(ref node); } }
public void Clear() { _root = null; _count = 0; }
public AVLNode GetNearestRight(TKey key) { return(AVLNode.GetNearestRight(_root, key, _comparison)); }
public void Add(TKey key, TValue value) { AVLNode <TKey, TValue> .Add(ref _root, key, value, _comparer); Count++; }
public void Bound(TKey key, out AVLNode <TKey, TValue>?lower, out AVLNode <TKey, TValue>?upper) { AVLNode <TKey, TValue> .Bound(_root, key, _comparer, out lower, out upper); }
public AVLTree() { _root = null; _comparer = Comparer <TKey> .Default; }
public AVLTree(IComparer <TKey> comparer) { _root = null; _comparer = comparer ?? Comparer <TKey> .Default; }
public AVLNode GetNearestLeft(TKey key) { return(AVLNode.GetNearestLeft(_root, key, _comparer)); }
internal static AVLNode RemoveNearestLeft(ref AVLNode node, TKey key, IComparer <TKey> comparer) { AVLNode result = null; return(RemoveNearestLeftExtracted(ref node, ref result, key, comparer)); }
public AVLNode RemoveNearestLeft(TKey key) { return(AVLNode.RemoveNearestLeft(ref _root, key, _comparer)); }
public void Add(TKey key, TValue value) { AVLNode.Add(ref _root, key, value, _comparison); _count++; }
public IEnumerator <AVLNode <TKey, TValue> > GetEnumerator() { return(AVLNode <TKey, TValue> .EnumerateRoot(_root).GetEnumerator()); }
public void Bound(TKey key, out AVLNode lower, out AVLNode upper) { AVLNode.Bound(_root, key, _comparison, out lower, out upper); }
public AVLNode <TKey, TValue>?GetNearestRight(TKey key) { return(AVLNode <TKey, TValue> .GetNearestRight(_root, key, _comparer)); }
public IEnumerator <AVLNode> GetEnumerator() { return(AVLNode.EnumerateRoot(_root).GetEnumerator()); }
private static AVLNode <TKey, TValue> GetOrAddExtracted(ref AVLNode <TKey, TValue>?node, TKey key, Func <TKey, TValue> factory, IComparer <TKey> comparer, AVLNode <TKey, TValue>?created, out bool isNew) { if (node == null) { if (created == null) { created = new AVLNode <TKey, TValue>(key, factory(key)); } var found = Interlocked.CompareExchange(ref node, created, null); if (found == null) { isNew = true; return(created); } node = found; } var compare = comparer.Compare(key, node.Key); if (compare == 0) { isNew = false; return(node); } try { return(compare < 0 ? GetOrAddExtracted(ref node._left, key, factory, comparer, created, out isNew) : GetOrAddExtracted(ref node._right, key, factory, comparer, created, out isNew)); } finally { MakeBalanced(ref node); } }
internal static AVLNode <TKey, TValue> GetOrAdd(ref AVLNode <TKey, TValue> node, TKey key, Func <TKey, TValue> factory, IComparer <TKey> comparer, out bool isNew) { return(GetOrAddExtracted(ref node, key, factory, comparer, null, out isNew)); }
public AVLNode RemoveNearestRight(TKey key) { return(AVLNode.RemoveNearestRight(ref _root, key, _comparison)); }
private static void AddExtracted(ref AVLNode <TKey, TValue>?node, TKey key, IComparer <TKey> comparer, AVLNode <TKey, TValue> created) { #if DEBUG // NOTICE this method has no null check in the public build as an optimization, this is just to appease the dragons if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } #endif // Ok, it has for node only int compare; if (node == null || (compare = comparer.Compare(key, node.Key)) == 0) { if (Interlocked.CompareExchange(ref node, created, null) == null) { return; } compare = -node._balance; } if (compare < 0) { AddExtracted(ref node._left, key, comparer, created); } else { AddExtracted(ref node._right, key, comparer, created); } MakeBalanced(ref node); }
public AVLTree() { _root = null; _comparison = Comparer <TKey> .Default.Compare; }
private static AVLNode <TKey, TValue> GetOrAddExtracted(ref AVLNode <TKey, TValue> node, TKey key, Func <TKey, TValue> factory, IComparer <TKey> comparer, AVLNode <TKey, TValue> created, out bool isNew) { #if DEBUG // NOTICE this method has no null check in the public build as an optimization, this is just to appease the dragons if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } #endif // Ok, it has for node only if (node == null) { if (created == null) { created = new AVLNode <TKey, TValue>(key, factory(key)); factory = null; } var found = Interlocked.CompareExchange(ref node, created, null); if (found == null) { isNew = true; return(created); } node = found; } var compare = comparer.Compare(key, node.Key); if (compare == 0) { isNew = false; return(node); } try { return(compare < 0 ? GetOrAddExtracted(ref node._left, key, factory, comparer, created, out isNew) : GetOrAddExtracted(ref node._right, key, factory, comparer, created, out isNew)); } finally { MakeBalanced(ref node); } }
public AVLTree(IComparer <TKey> comparer) { _root = null; _comparison = (comparer ?? Comparer <TKey> .Default).Compare; }
internal static bool AddNonDuplicate(ref AVLNode <TKey, TValue>?node, TKey key, TValue value, IComparer <TKey> comparer) { return(AddNonDuplicateExtracted(ref node, key, value, comparer, null)); }
public AVLTree(Comparison <TKey> comparison) { _root = null; _comparison = comparison ?? Comparer <TKey> .Default.Compare; }
public AVLNode <TKey, TValue>?RemoveNearestRight(TKey key) { return(AVLNode <TKey, TValue> .RemoveNearestRight(ref _root, key, _comparer)); }
private static void AddExtracted(ref AVLNode <TKey, TValue>?node, TKey key, IComparer <TKey> comparer, AVLNode <TKey, TValue> created) { // Ok, it has for node only int compare; if (node == null || (compare = comparer.Compare(key, node.Key)) == 0) { if (Interlocked.CompareExchange(ref node, created, null) == null) { return; } compare = -node._balance; } if (compare < 0) { AddExtracted(ref node._left, key, comparer, created); } else { AddExtracted(ref node._right, key, comparer, created); } MakeBalanced(ref node); }