using System.Collections.Generic; using MemoryPools.Collections.Specialized; namespace MemoryPools.Collections.Linq { internal class IntersectExprEnumerable : IPoolingEnumerable { private int _count; private IPoolingEnumerable _src; private IEqualityComparer _comparer; private PoolingDictionary _second; public IntersectExprEnumerable Init( IPoolingEnumerable src, PoolingDictionary second, IEqualityComparer comparer = default) { _src = src; _count = 0; _second = second; _comparer = comparer ?? EqualityComparer.Default; return this; } public IPoolingEnumerator GetEnumerator() { _count++; return Pool.Get().Init(this, _src.GetEnumerator(), _comparer); } private void Dispose() { if(_count == 0) return; _count--; if (_count == 0) { _src = default; _second?.Dispose(); Pool>.Return(_second); _second = default; Pool>.Return(this); } } internal class IntersectExprEnumerator : IPoolingEnumerator { private IntersectExprEnumerable _parent; private IPoolingEnumerator _src; private PoolingDictionary _alreadyDoneItems; public IntersectExprEnumerator Init(IntersectExprEnumerable parent, IPoolingEnumerator src, IEqualityComparer comparer) { _src = src; _parent = parent; _alreadyDoneItems = Pool>.Get().Init(0, comparer); return this; } public bool MoveNext() { while (_src.MoveNext()) { if (_parent._second.ContainsKey(_src.Current) && !_alreadyDoneItems.ContainsKey(_src.Current)) { _alreadyDoneItems[_src.Current] = 1; return true; } } return false; } public void Reset() => _src.Reset(); object IPoolingEnumerator.Current => Current; public T Current => _src.Current; public void Dispose() { _src?.Dispose(); _src = null; _alreadyDoneItems?.Dispose(); Pool>.Return(_alreadyDoneItems); _alreadyDoneItems = default; _parent?.Dispose(); _parent = default; Pool.Return(this); } } IPoolingEnumerator IPoolingEnumerable.GetEnumerator() => GetEnumerator(); } }