RefCountList.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. namespace System.Linq
  7. {
  8. internal sealed class RefCountList<T> : IRefCountList<T>
  9. {
  10. private int _readerCount;
  11. private readonly IDictionary<int, RefCount> _list;
  12. private int _count;
  13. public RefCountList(int readerCount)
  14. {
  15. _readerCount = readerCount;
  16. _list = new Dictionary<int, RefCount>();
  17. }
  18. public int ReaderCount
  19. {
  20. get => _readerCount;
  21. set => _readerCount = value;
  22. }
  23. public void Clear() => _list.Clear();
  24. public int Count => _count;
  25. public T this[int i]
  26. {
  27. get
  28. {
  29. Debug.Assert(i < _count);
  30. if (!_list.TryGetValue(i, out var res))
  31. throw new InvalidOperationException("Element no longer available in the buffer.");
  32. var val = res.Value;
  33. if (--res.Count == 0)
  34. {
  35. _list.Remove(i);
  36. }
  37. return val;
  38. }
  39. }
  40. public void Add(T item)
  41. {
  42. _list[_count] = new RefCount { Value = item, Count = _readerCount };
  43. _count++;
  44. }
  45. public void Done(int index)
  46. {
  47. for (var i = index; i < _count; i++)
  48. {
  49. var ignore = this[i];
  50. }
  51. _readerCount--;
  52. }
  53. private sealed class RefCount
  54. {
  55. public int Count;
  56. public T Value;
  57. }
  58. }
  59. }