상속: FdbSafeHandle
예제 #1
0
        public static FdbError FutureGetVersion(FutureHandle future, out long version)
        {
#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("fdb_future_get_version(0x" + future.Handle.ToString("x") + ")");
#endif
            return(NativeMethods.fdb_future_get_version(future, out version));
        }
예제 #2
0
        public Task <Slice[]> GetKeysAsync(KeySelector[] selectors, bool snapshot, CancellationToken ct)
        {
            Contract.Requires(selectors != null);

            if (selectors.Length == 0)
            {
                return(Task.FromResult(Array.Empty <Slice>()));
            }

            var futures = new FutureHandle[selectors.Length];

            try
            {
                for (int i = 0; i < selectors.Length; i++)
                {
                    futures[i] = FdbNative.TransactionGetKey(m_handle, selectors[i], snapshot);
                }
            }
            catch
            {
                for (int i = 0; i < selectors.Length; i++)
                {
                    if (futures[i] == null)
                    {
                        break;
                    }
                    futures[i].Dispose();
                }
                throw;
            }
            return(FdbFuture.CreateTaskFromHandleArray(futures, (h) => GetKeyResult(h), ct));
        }
예제 #3
0
        public Task <Slice[]> GetValuesAsync(ReadOnlySpan <Slice> keys, bool snapshot, CancellationToken ct)
        {
            Contract.Requires(keys != null);

            if (keys.Length == 0)
            {
                return(Task.FromResult(Array.Empty <Slice>()));
            }

            var futures = new FutureHandle[keys.Length];

            try
            {
                //REVIEW: as of now (700), there is no way to read multiple keys in a single API call
                for (int i = 0; i < keys.Length; i++)
                {
                    futures[i] = FdbNative.TransactionGet(m_handle, keys[i].Span, snapshot);
                }
            }
            catch
            {
                // cancel all requests leading up to the failure
                for (int i = 0; i < futures.Length; i++)
                {
                    if (futures[i] == null)
                    {
                        break;
                    }
                    futures[i].Dispose();
                }
                throw;
            }
            return(FdbFuture.CreateTaskFromHandleArray(futures, (h) => GetValueResultBytes(h), ct));
        }
        public Task <Slice[]> GetValuesAsync(Slice[] keys, bool snapshot, CancellationToken cancellationToken)
        {
            Contract.Requires(keys != null);

            if (keys.Length == 0)
            {
                return(Task.FromResult(Array.Empty <Slice>()));
            }

            var futures = new FutureHandle[keys.Length];

            try
            {
                for (int i = 0; i < keys.Length; i++)
                {
                    futures[i] = FdbNative.TransactionGet(m_handle, keys[i], snapshot);
                }
            }
            catch
            {
                for (int i = 0; i < keys.Length; i++)
                {
                    if (futures[i] == null)
                    {
                        break;
                    }
                    futures[i].Dispose();
                }
                throw;
            }
            return(FdbFuture.CreateTaskFromHandleArray(futures, (h) => GetValueResultBytes(h), cancellationToken));
        }
예제 #5
0
        public static FdbError FutureSetCallback(FutureHandle future, FdbFutureCallback callback, IntPtr callbackParameter)
        {
            var err = NativeMethods.fdb_future_set_callback(future, callback, callbackParameter);

#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("fdb_future_set_callback(0x" + future.Handle.ToString("x") + ", 0x" + ptrCallback.ToString("x") + ") => err=" + err);
#endif
            return(err);
        }
예제 #6
0
        private static KeyValuePair <Slice, Slice>[] GetKeyValueArrayResult(FutureHandle h, out bool more)
        {
            var err = FdbNative.FutureGetKeyValueArray(h, out var result, out more);

            Fdb.DieOnError(err);
            //note: result can only be null if an error occured!
            Contract.Ensures(result != null);
            return(result);
        }
예제 #7
0
        private static Slice GetValueResultBytes(FutureHandle h)
        {
            Contract.Requires(h != null);

            if (!TryGetValueResult(h, out Slice result))
            {
                return(Slice.Nil);
            }
            return(result);
        }
예제 #8
0
        public static FdbError FutureGetCluster(FutureHandle future, out ClusterHandle cluster)
        {
            var err = NativeMethods.fdb_future_get_cluster(future, out cluster);

#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("fdb_future_get_cluster(0x" + future.Handle.ToString("x") + ") => err=" + err + ", handle=0x" + cluster.Handle.ToString("x"));
#endif
            //TODO: check if err == Success ?
            return(err);
        }
예제 #9
0
        public static FdbError FutureGetDatabase(FutureHandle future, out DatabaseHandle database)
        {
            var err = NativeMethods.fdb_future_get_database(future, out database);

#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("fdb_future_get_database(0x" + future.Handle.ToString("x") + ") => err=" + err + ", handle=0x" + database.Handle.ToString("x"));
#endif
            //TODO: check if err == Success ?
            return(err);
        }
예제 #10
0
        public static FdbError FutureBlockUntilReady(FutureHandle future)
        {
#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("calling fdb_future_block_until_ready(0x" + future.Handle.ToString("x") + ")...");
#endif
            var err = NativeMethods.fdb_future_block_until_ready(future);
#if DEBUG_NATIVE_CALLS
            Debug.WriteLine("fdb_future_block_until_ready(0x" + future.Handle.ToString("x") + ") => err=" + err);
#endif
            return(err);
        }
예제 #11
0
        /// <summary>Extract a chunk of result from a completed Future</summary>
        /// <param name="h">Handle to the completed Future</param>
        /// <param name="more">Receives true if there are more result, or false if all results have been transmitted</param>
        /// <param name="first">Receives the first key in the page, or default if page is empty</param>
        /// <param name="last">Receives the last key in the page, or default if page is empty</param>
        /// <returns>Array of key/value pairs, or an exception</returns>
        private static KeyValuePair <Slice, Slice>[] GetKeyValueArrayResultKeysOnly(FutureHandle h, out bool more, out Slice first, out Slice last)
        {
            var err = FdbNative.FutureGetKeyValueArrayKeysOnly(h, out var result, out more);

            Fdb.DieOnError(err);
            //note: result can only be null if an error occured!
            Contract.Ensures(result != null);
            first = result.Length > 0 ? result[0].Key : default;
            last  = result.Length > 0 ? result[result.Length - 1].Key : default;
            return(result);
        }
예제 #12
0
        private static bool TryGetValueResult(FutureHandle h, out Slice result)
        {
            Contract.Requires(h != null);

            var err = FdbNative.FutureGetValue(h, out bool present, out result);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[].TryGetValueResult() => err=" + err + ", present=" + present + ", valueLength=" + result.Count);
#endif
            Fdb.DieOnError(err);
            return(present);
        }
예제 #13
0
        private static Slice GetKeyResult(FutureHandle h)
        {
            Contract.Requires(h != null);

            var err = FdbNative.FutureGetKey(h, out ReadOnlySpan <byte> result);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[].GetKeyResult() => err=" + err + ", result=" + result.ToString());
#endif
            Fdb.DieOnError(err);
            return(Slice.Copy(result));
        }
예제 #14
0
        private static VersionStamp GetVersionStampResult(FutureHandle h)
        {
            Contract.Requires(h != null);
            var err = FdbNative.FutureGetVersionStamp(h, out VersionStamp stamp);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[" + m_id + "].FutureGetVersionStamp() => err=" + err + ", vs=" + stamp + ")");
#endif
            Fdb.DieOnError(err);

            return(stamp);
        }
예제 #15
0
        private static Slice GetValueResultBytes(FutureHandle h)
        {
            Contract.Debug.Requires(h != null);

            var err = FdbNative.FutureGetValue(h, out bool present, out ReadOnlySpan <byte> result);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[].TryGetValueResult() => err=" + err + ", present=" + present + ", valueLength=" + result.Count);
#endif
            Fdb.DieOnError(err);

            return(present ? Slice.Copy(result) : Slice.Nil);
        }
예제 #16
0
        private static string[] GetStringArrayResult(FutureHandle h)
        {
            Contract.Requires(h != null);

            var err = FdbNative.FutureGetStringArray(h, out var result);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[].FutureGetStringArray() => err=" + err + ", results=" + (result == null ? "<null>" : result.Length.ToString()));
#endif
            Fdb.DieOnError(err);
            Contract.Ensures(result != null);             // can only be null in case of an error
            return(result !);
        }
예제 #17
0
 public static void FutureReleaseMemory(FutureHandle futureHandle)
 {
     NativeMethods.fdb_future_release_memory(futureHandle);
 }
예제 #18
0
 public static bool FutureIsReady(FutureHandle futureHandle)
 {
     return(NativeMethods.fdb_future_is_ready(futureHandle));
 }
예제 #19
0
 public static extern FdbError fdb_future_get_string_array(FutureHandle future, out byte **strings, out int count);
예제 #20
0
 public static extern FdbError fdb_future_get_database(FutureHandle future, out DatabaseHandle database);
		public static FdbError FutureGetError(FutureHandle future)
		{
			return NativeMethods.fdb_future_get_error(future);
		}
			public static extern FdbError fdb_future_get_error(FutureHandle futureHandle);
			public static extern FdbError fdb_future_get_key(FutureHandle future, out byte* key, out int keyLength);
		public static FdbError FutureGetValue(FutureHandle future, out bool valuePresent, out Slice value)
		{
			byte* ptr;
			int valueLength;
			var err = NativeMethods.fdb_future_get_value(future, out valuePresent, out ptr, out valueLength);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_value(0x" + future.Handle.ToString("x") + ") => err=" + err + ", present=" + valuePresent + ", valueLength=" + valueLength);
#endif
			if (ptr != null && valueLength >= 0)
			{
				var bytes = new byte[valueLength];
				Marshal.Copy(new IntPtr(ptr), bytes, 0, valueLength);
				value = new Slice(bytes, 0, valueLength);
			}
			else
			{
				value = Slice.Nil;
			}
			return err;
		}
		public static FdbError FutureGetVersion(FutureHandle future, out long version)
		{
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_version(0x" + future.Handle.ToString("x") + ")");
#endif
			return NativeMethods.fdb_future_get_version(future, out version);
		}
		public static FdbError FutureGetDatabase(FutureHandle future, out DatabaseHandle database)
		{
			var err = NativeMethods.fdb_future_get_database(future, out database);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_database(0x" + future.Handle.ToString("x") + ") => err=" + err + ", handle=0x" + database.Handle.ToString("x"));
#endif
			//TODO: check if err == Success ?
			return err;
		}
		public static FdbError FutureGetCluster(FutureHandle future, out ClusterHandle cluster)
		{
			var err = NativeMethods.fdb_future_get_cluster(future, out cluster);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_cluster(0x" + future.Handle.ToString("x") + ") => err=" + err + ", handle=0x" + cluster.Handle.ToString("x"));
#endif
			//TODO: check if err == Success ?
			return err;
		}
		public static FdbError FutureSetCallback(FutureHandle future, FdbFutureCallback callback, IntPtr callbackParameter)
		{
			var err = NativeMethods.fdb_future_set_callback(future, callback, callbackParameter);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_set_callback(0x" + future.Handle.ToString("x") + ", 0x" + ptrCallback.ToString("x") + ") => err=" + err);
#endif
			return err;
		}
		public static FdbError FutureBlockUntilReady(FutureHandle future)
		{
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("calling fdb_future_block_until_ready(0x" + future.Handle.ToString("x") + ")...");
#endif
			var err = NativeMethods.fdb_future_block_until_ready(future);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_block_until_ready(0x" + future.Handle.ToString("x") + ") => err=" + err);
#endif
			return err;
		}
			public static extern FdbError fdb_future_get_string_array(FutureHandle future, out byte** strings, out int count);
			public static extern FdbError fdb_future_get_database(FutureHandle future, out DatabaseHandle database);
		public static FdbError FutureGetKey(FutureHandle future, out Slice key)
		{
			byte* ptr;
			int keyLength;
			var err = NativeMethods.fdb_future_get_key(future, out ptr, out keyLength);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_key(0x" + future.Handle.ToString("x") + ") => err=" + err + ", keyLength=" + keyLength);
#endif

			// note: fdb_future_get_key is allowed to return NULL for the empty key (not to be confused with a key that has an empty value)
			Contract.Assert(keyLength >= 0 && keyLength <= Fdb.MaxKeySize);

			if (keyLength <= 0 || ptr == null)
			{ // from the spec: "If a key selector would otherwise describe a key off the beginning of the database, it instead resolves to the empty key ''."
				key = Slice.Empty;
			}
			else
			{
				key = Slice.Create(ptr, keyLength);
			}
			return err;
		}
			public static extern FdbError fdb_future_get_version(FutureHandle future, out long version);
		public static FdbError FutureGetKeyValueArray(FutureHandle future, out KeyValuePair<Slice, Slice>[] result, out bool more)
		{
			result = null;

			int count;
			FdbKeyValue* kvp;

			var err = NativeMethods.fdb_future_get_keyvalue_array(future, out kvp, out count, out more);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_keyvalue_array(0x" + future.Handle.ToString("x") + ") => err=" + err + ", count=" + count + ", more=" + more);
#endif

			if (Fdb.Success(err))
			{
				Contract.Assert(count >= 0, "Return count was negative");

				result = new KeyValuePair<Slice, Slice>[count];

				if (count > 0)
				{ // convert the keyvalue result into an array

					Contract.Assert(kvp != null, "We have results but array pointer was null");

					// in order to reduce allocations, we want to merge all keys and values
					// into a single byte{] and return  list of Slice that will
					// link to the different chunks of this buffer.

					// first pass to compute the total size needed
					int total = 0;
					for (int i = 0; i < count; i++)
					{
						//TODO: protect against negative values or values too big ?
						Contract.Assert(kvp[i].KeyLength >= 0 && kvp[i].ValueLength >= 0);
						total += kvp[i].KeyLength + kvp[i].ValueLength;
					}

					// allocate all memory in one chunk, and make the key/values point to it
					// Does fdb allocate all keys into a single buffer ? We could copy everything in one pass,
					// but it would rely on implementation details that could break at anytime...

					//TODO: protect against too much memory allocated ?
					// what would be a good max value? we need to at least be able to handle FDB_STREAMING_MODE_WANT_ALL

					var page = new byte[total];
					int p = 0;
					for (int i = 0; i < result.Length; i++)
					{
						int kl = kvp[i].KeyLength;
						int vl = kvp[i].ValueLength;

						//TODO: some keys/values will be small (32 bytes or less) while other will be big
						//consider having to copy methods, optimized for each scenario ?

						Marshal.Copy(kvp[i].Key, page, p, kl);
						Marshal.Copy(kvp[i].Value, page, p + kl, vl);

						result[i] = new KeyValuePair<Slice, Slice>(
							new Slice(page, p, kl),
							new Slice(page, p + kl, vl)
						);

						p += kl + vl;
					}
					Contract.Assert(p == total);
				}
			}

			return err;
		}
		public static FdbError FutureGetStringArray(FutureHandle future, out string[] result)
		{
			result = null;

			int count;
			byte** strings;

			var err = NativeMethods.fdb_future_get_string_array(future, out strings, out count);
#if DEBUG_NATIVE_CALLS
			Debug.WriteLine("fdb_future_get_string_array(0x" + future.Handle.ToString("x") + ") => err=" + err + ", count=" + count);
#endif

			if (Fdb.Success(err))
			{
				Contract.Assert(count >= 0, "Return count was negative");

				result = new string[count];

				if (count > 0)
				{ // convert the keyvalue result into an array

					Contract.Assert(strings != null, "We have results but array pointer was null");

					//TODO: if pointers are corrupted, or memory is garbled, we could very well walk around the heap, randomly copying a bunch of stuff (like passwords or jpegs of cats...)
					// there is no real way to ensure that pointers are valid, except maybe having a maximum valid size for strings, and they should probably only contain legible text ?

					for (int i = 0; i < result.Length; i++)
					{
						result[i] = ToManagedString(strings[i]);
					}
				}
			}

			return err;
		}
		private static bool TryGetValueResult(FutureHandle h, out Slice result)
		{
			Contract.Requires(h != null);

			bool present;
			var err = FdbNative.FutureGetValue(h, out present, out result);
#if DEBUG_TRANSACTIONS
			Debug.WriteLine("FdbTransaction[].TryGetValueResult() => err=" + err + ", present=" + present + ", valueLength=" + result.Count);
#endif
			Fdb.DieOnError(err);
			return present;
		}
예제 #37
0
 public static extern FdbError fdb_future_get_cluster(FutureHandle future, out ClusterHandle cluster);
		private static Slice GetValueResultBytes(FutureHandle h)
		{
			Contract.Requires(h != null);

			Slice result;
			if (!TryGetValueResult(h, out result))
			{
				return Slice.Nil;
			}
			return result;
		}
예제 #39
0
 public static extern FdbError fdb_future_get_value(FutureHandle future, out bool present, out byte *value, out int valueLength);
		public Task<Slice[]> GetValuesAsync(Slice[] keys, bool snapshot, CancellationToken cancellationToken)
		{
			Contract.Requires(keys != null);

			if (keys.Length == 0) return Task.FromResult(Slice.EmptySliceArray);

			var futures = new FutureHandle[keys.Length];
			try
			{
				for (int i = 0; i < keys.Length; i++)
				{
					futures[i] = FdbNative.TransactionGet(m_handle, keys[i], snapshot);
				}
			}
			catch
			{
				for (int i = 0; i < keys.Length; i++)
				{
					if (futures[i] == null) break;
					futures[i].Dispose();
				}
				throw;
			}
			return FdbFuture.CreateTaskFromHandleArray(futures, (h) => GetValueResultBytes(h), cancellationToken);
		}
예제 #41
0
 public static extern FdbError fdb_future_get_keyvalue_array(FutureHandle future, out FdbKeyValue *kv, out int count, out bool more);
 /// <summary>Create a new <see cref="FdbFutureSingle{T}"/> from an FDBFuture* pointer</summary>
 /// <typeparam name="T">Type of the result of the task</typeparam>
 /// <param name="handle">FDBFuture* pointer</param>
 /// <param name="selector">Func that will be called to get the result once the future completes (and did not fail)</param>
 /// <param name="ct">Optional cancellation token that can be used to cancel the future</param>
 /// <returns>Object that tracks the execution of the FDBFuture handle</returns>
 public static FdbFutureSingle <T> FromHandle <T>(FutureHandle handle, Func <FutureHandle, T> selector, CancellationToken ct)
 {
     return(new FdbFutureSingle <T>(handle, selector, ct));
 }
예제 #43
0
 public static void FutureCancel(FutureHandle futureHandle)
 {
     NativeMethods.fdb_future_cancel(futureHandle);
 }
		public static void FutureCancel(FutureHandle futureHandle)
		{
			NativeMethods.fdb_future_cancel(futureHandle);
		}
예제 #45
0
 public static FdbError FutureGetError(FutureHandle future)
 {
     return(NativeMethods.fdb_future_get_error(future));
 }
		public Task<Slice[]> GetKeysAsync(FdbKeySelector[] selectors, bool snapshot, CancellationToken cancellationToken)
		{
			Contract.Requires(selectors != null);

			var futures = new FutureHandle[selectors.Length];
			try
			{
				for (int i = 0; i < selectors.Length; i++)
				{
					futures[i] = FdbNative.TransactionGetKey(m_handle, selectors[i], snapshot);
				}
			}
			catch
			{
				for (int i = 0; i < selectors.Length; i++)
				{
					if (futures[i] == null) break;
					futures[i].Dispose();
				}
				throw;
			}
			return FdbFuture.CreateTaskFromHandleArray(futures, (h) => GetKeyResult(h), cancellationToken);

		}
			public static extern FdbError fdb_future_get_value(FutureHandle future, out bool present, out byte* value, out int valueLength);
		private static string[] GetStringArrayResult(FutureHandle h)
		{
			Contract.Requires(h != null);

			string[] result;
			var err = FdbNative.FutureGetStringArray(h, out result);
#if DEBUG_TRANSACTIONS
			Debug.WriteLine("FdbTransaction[].FutureGetStringArray() => err=" + err + ", results=" + (result == null ? "<null>" : result.Length.ToString()));
#endif
			Fdb.DieOnError(err);
			Contract.Ensures(result != null); // can only be null in case of an errror
			return result;
		}
			public static extern FdbError fdb_future_get_cluster(FutureHandle future, out ClusterHandle cluster);
		public static bool FutureIsReady(FutureHandle futureHandle)
		{
			return NativeMethods.fdb_future_is_ready(futureHandle);
		}
예제 #51
0
 public static FdbFutureSingle <T> FromHandle <T>([NotNull] FutureHandle handle, [NotNull] Func <FutureHandle, T> selector, CancellationToken cancellationToken)
 {
     return(new FdbFutureSingle <T>(handle, selector, cancellationToken));
 }
			public static extern FdbError fdb_future_get_keyvalue_array(FutureHandle future, out FdbKeyValue* kv, out int count, out bool more);
			public static extern FdbError fdb_future_set_callback(FutureHandle future, FdbFutureCallback callback, IntPtr callbackParameter);
예제 #54
0
 public static extern FdbError fdb_future_get_version(FutureHandle future, out long version);
			public static extern bool fdb_future_is_ready(FutureHandle futureHandle);
예제 #56
0
 public static extern FdbError fdb_future_get_key(FutureHandle future, out byte *key, out int keyLength);
		private static KeyValuePair<Slice, Slice>[] GetKeyValueArrayResult(FutureHandle h, out bool more)
		{
			KeyValuePair<Slice, Slice>[] result;
			var err = FdbNative.FutureGetKeyValueArray(h, out result, out more);
			Fdb.DieOnError(err);
			//note: result can only be null if an error occured!
			Contract.Ensures(result != null);
			return result;
		}
		public static void FutureReleaseMemory(FutureHandle futureHandle)
		{
			NativeMethods.fdb_future_release_memory(futureHandle);
		}
 /// <summary>Wrap a FDBFuture* pointer into a <see cref="Task{T}"/></summary>
 /// <typeparam name="T">Type of the result of the task</typeparam>
 /// <param name="handle">FDBFuture* pointer</param>
 /// <param name="continuation">Lambda that will be called once the future completes successfully, to extract the result from the future handle.</param>
 /// <param name="ct">Optional cancellation token that can be used to cancel the future</param>
 /// <returns>Task that will either return the result of the continuation lambda, or an exception</returns>
 public static Task <T> CreateTaskFromHandle <T>(FutureHandle handle, Func <FutureHandle, T> continuation, CancellationToken ct)
 {
     return(new FdbFutureSingle <T>(handle, continuation, ct).Task);
 }
		private static Slice GetKeyResult(FutureHandle h)
		{
			Contract.Requires(h != null);

			Slice result;
			var err = FdbNative.FutureGetKey(h, out result);
#if DEBUG_TRANSACTIONS
			Debug.WriteLine("FdbTransaction[].GetKeyResult() => err=" + err + ", result=" + result.ToString());
#endif
			Fdb.DieOnError(err);
			return result;
		}