当前位置: 首页>>代码示例>>C#>>正文


C# Slice.Memoize方法代码示例

本文整理汇总了C#中Slice.Memoize方法的典型用法代码示例。如果您正苦于以下问题:C# Slice.Memoize方法的具体用法?C# Slice.Memoize怎么用?C# Slice.Memoize使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Slice的用法示例。


在下文中一共展示了Slice.Memoize方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: EstimateCountAsync

			/// <summary>Estimate the number of keys in the specified range.</summary>
			/// <param name="db">Database used for the operation</param>
			/// <param name="beginInclusive">Key defining the beginning of the range</param>
			/// <param name="endExclusive">Key defining the end of the range</param>
			/// <param name="onProgress">Optional callback called everytime the count is updated. The first argument is the current count, and the second argument is the last key that was found.</param>
			/// <param name="cancellationToken">Token used to cancel the operation</param>
			/// <returns>Number of keys k such that <paramref name="beginInclusive"/> &lt;= k &gt; <paramref name="endExclusive"/></returns>
			/// <remarks>If the range contains a large of number keys, the operation may need more than one transaction to complete, meaning that the number will not be transactionally accurate.</remarks>
			public static async Task<long> EstimateCountAsync([NotNull] IFdbDatabase db, Slice beginInclusive, Slice endExclusive, IProgress<FdbTuple<long, Slice>> onProgress, CancellationToken cancellationToken)
			{
				const int INIT_WINDOW_SIZE = 1 << 8; // start at 256 //1024
				const int MAX_WINDOW_SIZE = 1 << 13; // never use more than 4096
				const int MIN_WINDOW_SIZE = 64; // use range reads when the windows size is smaller than 64

				if (db == null) throw new ArgumentNullException("db");
				if (endExclusive < beginInclusive) throw new ArgumentException("The end key cannot be less than the begin key", "endExclusive");

				cancellationToken.ThrowIfCancellationRequested();

				// To count the number of items in the range, we will scan it using a key selector with an offset equal to our window size
				// > if the returned key is still inside the range, we add the window size to the counter, and start again from the current key
				// > if the returned key is outside the range, we reduce the size of the window, and start again from the previous key
				// > if the returned key is exactly equal to the end of range, OR if the window size was 1, then we stop

				// Since we don't know in advance if the range contains 1 key or 1 Billion keys, choosing a good value for the window size is critical:
				// > if it is too small and the range is very large, we will need too many sequential reads and the network latency will quickly add up
				// > if it is too large and the range is small, we will spend too many times halving the window size until we get the correct value

				// A few optimizations are possible:
				// > we could start with a small window size, and then double its size on every full segment (up to a maximum)
				// > for the last segment, we don't need to wait for a GetKey to complete before issuing the next, so we could split the segment into 4 (or more), do the GetKeyAsync() in parallel, detect the quarter that cross the boundary, and iterate again until the size is small
				// > once the window size is small enough, we can switch to using GetRange to read the last segment in one shot, instead of iterating with window size 16, 8, 4, 2 and 1 (the wost case being 2^N - 1 items remaning)

				// note: we make a copy of the keys because the operation could take a long time and the key's could prevent a potentially large underlying buffer from being GCed
				var cursor = beginInclusive.Memoize();
				var end = endExclusive.Memoize();

				using (var tr = db.BeginReadOnlyTransaction(cancellationToken))
				{
#if TRACE_COUNTING
					tr.Annotate("Estimating number of keys in range {0}", FdbKeyRange.Create(beginInclusive, endExclusive));
#endif

					tr.SetOption(FdbTransactionOption.ReadYourWritesDisable);

					// start looking for the first key in the range
					cursor = await tr.Snapshot.GetKeyAsync(FdbKeySelector.FirstGreaterOrEqual(cursor)).ConfigureAwait(false);
					if (cursor >= end)
					{ // the range is empty !
						return 0;
					}

					// we already have seen one key, so add it to the count
#if TRACE_COUNTING
					int iter = 1;
#endif
					long counter = 1;
					// start with a medium-sized window
					int windowSize = INIT_WINDOW_SIZE;
					bool last = false;

					while (cursor < end)
					{
						Contract.Assert(windowSize > 0);

						var selector = FdbKeySelector.FirstGreaterOrEqual(cursor) + windowSize;
						Slice next = Slice.Nil;
						FdbException error = null;
						try
						{
							next = await tr.Snapshot.GetKeyAsync(selector).ConfigureAwait(false);
#if TRACE_COUNTING
							++iter;
#endif
						}
						catch (FdbException e)
						{
							error = e;
						}

						if (error != null)
						{
							// => from this point, the count returned will not be transactionally accurate
							if (error.Code == FdbError.PastVersion)
							{ // the transaction used up its time window
								tr.Reset();
							}
							else
							{ // check to see if we can continue...
								await tr.OnErrorAsync(error.Code).ConfigureAwait(false);
							}
							// retry
							tr.SetOption(FdbTransactionOption.ReadYourWritesDisable);
							continue;
						}

						//BUGBUG: GetKey(...) always truncate the result to \xFF if the selected key would be past the end,
						// so we need to fall back immediately to the binary search and/or get_range if next == \xFF

						if (next > end)
//.........这里部分代码省略.........
开发者ID:BedeGaming,项目名称:foundationdb-dotnet-client,代码行数:101,代码来源:Fdb.System.cs

示例2: Intern

		/// <summary>Copy a slice into the buffer, with optional alignement, and return a new identical slice.</summary>
		/// <param name="data">Data to copy in the buffer</param>
		/// <param name="aligned">If true, align the index of first byte of the slice with a multiple of 8 bytes</param>
		/// <returns>Slice that is the equivalent of <paramref name="data"/>, backed by the buffer.</returns>
		public Slice Intern(Slice data, bool aligned = false)
		{
			if (data.Count == 0)
			{
				// transform into the corresponding Slice.Nil / Slice.Empty singleton
				return data.Memoize();
			}

			SliceHelpers.EnsureSliceIsValid(ref data);

			// allocate the slice
			var slice = Allocate(data.Count, aligned);
			SliceHelpers.CopyBytesUnsafe(slice.Array, slice.Offset, data.Array, data.Offset, data.Count);
			return slice;
		}
开发者ID:BedeGaming,项目名称:foundationdb-dotnet-client,代码行数:19,代码来源:SliceBuffer.cs


注:本文中的Slice.Memoize方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。