合并主线最近几年来的主要更新,重点推进TinyHttpClient,替代HttpClient
大石头 authored at 2023-03-08 18:39:12
1.66 KiB
X_NET20
using System.Collections.Generic;

namespace System.Threading.Tasks
{
	internal class CyclicDeque<T> : IConcurrentDeque<T>
	{
		private const int BaseSize = 11;

		private long bottom;

		private long top;

		private long upperBound;

		private CircularArray<T> array = new CircularArray<T>(11);

		public void PushBottom(T obj)
		{
			long b = Interlocked.Read(ref bottom);
			CircularArray<T> a = array;
			if (b - upperBound >= a.Size - 1)
			{
				upperBound = Interlocked.Read(ref top);
				a = (array = a.Grow(b, upperBound));
			}
			a.segment[b % a.size] = obj;
			Interlocked.Increment(ref bottom);
		}

		public PopResult PopBottom(out T obj)
		{
			obj = default(T);
			long b = Interlocked.Decrement(ref bottom);
			CircularArray<T> a = array;
			long t = Interlocked.Read(ref top);
			long size = b - t;
			if (size < 0)
			{
				Interlocked.Add(ref bottom, t - b);
				return PopResult.Empty;
			}
			obj = a.segment[b % a.size];
			if (size > 0)
			{
				return PopResult.Succeed;
			}
			Interlocked.Add(ref bottom, t + 1 - b);
			if (Interlocked.CompareExchange(ref top, t + 1, t) != t)
			{
				return PopResult.Empty;
			}
			return PopResult.Succeed;
		}

		public PopResult PopTop(out T obj)
		{
			obj = default(T);
			long t = Interlocked.Read(ref top);
			long b = Interlocked.Read(ref bottom);
			if (b - t <= 0)
			{
				return PopResult.Empty;
			}
			if (Interlocked.CompareExchange(ref top, t + 1, t) != t)
			{
				return PopResult.Abort;
			}
			CircularArray<T> a = array;
			obj = a.segment[t % a.size];
			return PopResult.Succeed;
		}

		public IEnumerable<T> GetEnumerable()
		{
			CircularArray<T> a = array;
			return a.GetEnumerable(bottom, ref top);
		}
	}
}