v10.10.2024.0701 使用IJsonHost改进Json序列化
大石头 编写于 2024-07-01 08:36:34 大石头 提交于 2024-07-01 08:48:33
X
using System.Collections.Generic;
using System.Threading;

namespace System.Collections.Concurrent.Partitioners;

internal class UserLongRangePartitioner : OrderablePartitioner<Tuple<long, long>>
{
	private readonly long start;

	private readonly long end;

	private readonly long rangeSize;

	public UserLongRangePartitioner(long start, long end, long rangeSize)
		: base(keysOrderedInEachPartition: true, keysOrderedAcrossPartitions: true, keysNormalized: true)
	{
		this.start = start;
		this.end = end;
		this.rangeSize = rangeSize;
	}

	public override IList<IEnumerator<KeyValuePair<long, Tuple<long, long>>>> GetOrderablePartitions(int partitionCount)
	{
		if (partitionCount <= 0)
		{
			throw new ArgumentOutOfRangeException("partitionCount");
		}
		long currentIndex = 0L;
		Func<long> getNextIndex = () => Interlocked.Increment(ref currentIndex) - 1;
		IEnumerator<KeyValuePair<long, Tuple<long, long>>>[] array = new IEnumerator<KeyValuePair<long, Tuple<long, long>>>[partitionCount];
		for (int i = 0; i < partitionCount; i++)
		{
			array[i] = GetEnumerator(getNextIndex);
		}
		return array;
	}

	private IEnumerator<KeyValuePair<long, Tuple<long, long>>> GetEnumerator(Func<long> getNextIndex)
	{
		while (true)
		{
			long index = getNextIndex();
			long sliceStart = index * rangeSize + start;
			if (sliceStart < end)
			{
				yield return new KeyValuePair<long, Tuple<long, long>>(index, Tuple.Create(sliceStart, Math.Min(end, sliceStart + rangeSize)));
				_ = sliceStart + rangeSize;
				continue;
			}
			break;
		}
	}
}