public static IEnumerable <Slice> EncodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] IEnumerable <T> values)
        {
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            // note: T=>Slice usually is used for writing batches as fast as possible, which means that keys will be consumed immediately and don't need to be streamed

            var array = values as T[];

            if (array != null)
            {             // optimized path for arrays
                return(EncodeValues <T>(encoder, array));
            }

            var coll = values as ICollection <T>;

            if (coll != null)
            {             // optimized path when we know the count
                var slices = new List <Slice>(coll.Count);
                foreach (var value in coll)
                {
                    slices.Add(encoder.EncodeValue(value));
                }
                return(slices);
            }

            return(values.Select(value => encoder.EncodeValue(value)));
        }
示例#2
0
        /// <summary>Create a new sparse Vector</summary>
        /// <param name="location">Subspace where the vector will be stored</param>
        /// <param name="defaultValue">Default value for sparse entries</param>
        /// <param name="encoder">Encoder used for the values of this vector</param>
        public FdbVector(DynamicKeySubspaceLocation location, T defaultValue, IValueEncoder <T>?encoder = null)
        {
            Contract.NotNull(location, nameof(location));

            this.Location     = location;
            this.DefaultValue = defaultValue;
            this.Encoder      = encoder ?? TuPack.Encoding.GetValueEncoder <T>();
        }
        public static IEnumerable <T> DecodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] IEnumerable <Slice> slices)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(slices, nameof(slices));

            // Slice=>T may be filtered in LINQ queries, so we should probably stream the values (so no optimization needed)

            return(slices.Select(slice => encoder.DecodeValue(slice)));
        }
        public NullableValueEncoder(IValueEncoder <TValue> valueEncoder)
        {
            if (valueEncoder == null)
            {
                throw new ArgumentNullException(nameof(valueEncoder));
            }

            _valueEncoder = valueEncoder;
        }
示例#5
0
		/// <summary>Create a new High Contention counter, using a specific value encoder.</summary>
		/// <param name="db">Database used by this layer</param>
		/// <param name="subspace">Subspace to be used for storing the counter</param>
		/// <param name="encoder">Encoder for the counter values</param>
		public FdbHighContentionCounter(IFdbDatabase db, FdbSubspace subspace, IValueEncoder<long> encoder)
		{
			if (db == null) throw new ArgumentNullException("db");
			if (subspace == null) throw new ArgumentNullException("subspace");
			if (encoder == null) throw new ArgumentNullException("encoder");

			this.Database = db;
			this.Subspace = subspace;
			this.Encoder = encoder;
		}
        /// <summary>Create a new sparse Vector</summary>
        /// <param name="subspace">Subspace where the vector will be stored</param>
        /// <param name="defaultValue">Default value for sparse entries</param>
        /// <param name="encoder">Encoder used for the values of this vector</param>
        public FdbVector([NotNull] IDynamicKeySubspace subspace, T defaultValue, IValueEncoder <T> encoder = null)
        {
            if (subspace == null)
            {
                throw new ArgumentNullException(nameof(subspace));
            }

            this.Subspace     = subspace;
            this.DefaultValue = defaultValue;
            this.Encoder      = encoder ?? TuPack.Encoding.GetValueEncoder <T>();
        }
示例#7
0
        public static TValue[] DecodeValues <TValue, TStorage>([NotNull] this IValueEncoder <TValue, TStorage> encoder, [NotNull] params TStorage[] values)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(values, nameof(values));

            var res = new TValue[values.Length];

            for (int i = 0; i < res.Length; i++)
            {
                res[i] = encoder.DecodeValue(values[i]);
            }
            return(res);
        }
        public static T[] DecodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] params Slice[] slices)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(slices, nameof(slices));

            var values = new T[slices.Length];

            for (int i = 0; i < slices.Length; i++)
            {
                values[i] = encoder.DecodeValue(slices[i]);
            }

            return(values);
        }
        public static Slice[] EncodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] params T[] values)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(values, nameof(values));

            var slices = new Slice[values.Length];

            for (int i = 0; i < values.Length; i++)
            {
                slices[i] = encoder.EncodeValue(values[i]);
            }

            return(slices);
        }
        /// <summary>Encode a array of <typeparamref name="TValue"/> into an array of <typeparamref name="TStorage"/></summary>
        public static TStorage[] EncodeValues <TValue, TStorage>(this IValueEncoder <TValue, TStorage> encoder, params TValue[] values)
        {
            Contract.NotNull(encoder);
            Contract.NotNull(values);

            var slices = new TStorage[values.Length];

            for (int i = 0; i < values.Length; i++)
            {
                slices[i] = encoder.EncodeValue(values[i]);
            }

            return(slices);
        }
        public static T[] DecodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] KeyValuePair <Slice, Slice>[] items)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(items, nameof(items));

            var values = new T[items.Length];

            for (int i = 0; i < items.Length; i++)
            {
                values[i] = encoder.DecodeValue(items[i].Value);
            }

            return(values);
        }
        public T[] DecodeValues <T>([NotNull] IValueEncoder <T> valueEncoder)
        {
            if (valueEncoder == null)
            {
                throw new ArgumentNullException("valueEncoder");
            }

            var results = new T[this.Count];

            for (int i = 0; i < results.Length; i++)
            {
                results[i] = valueEncoder.DecodeValue(this.Chunk[i].Value);
            }
            return(results);
        }
        public static IEnumerable <T> DecodeRange <T>(this IValueEncoder <T> encoder, [NotNull] IEnumerable <Slice> slices)
        {
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (slices == null)
            {
                throw new ArgumentNullException("slices");
            }

            // Slice=>T may be filtered in LINQ queries, so we should probably stream the values (so no optimization needed)

            return(slices.Select(slice => encoder.DecodeValue(slice)));
        }
示例#14
0
        public FdbVector([NotNull] IFdbSubspace subspace, T defaultValue, [NotNull] IValueEncoder <T> encoder)
        {
            if (subspace == null)
            {
                throw new ArgumentNullException("subspace");
            }
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }

            this.Subspace     = subspace.Using(TypeSystem.Tuples);
            this.DefaultValue = defaultValue;
            this.Encoder      = encoder;
        }
示例#15
0
        public static TValue[] DecodeValues <TValue, TStorage, TAny>([NotNull] this IValueEncoder <TValue, TStorage> encoder, [NotNull] IEnumerable <KeyValuePair <TAny, TStorage> > items)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(items, nameof(items));

            switch (items)
            {
            case KeyValuePair <TAny, TStorage>[] array:
            {
                var res = new TValue[array.Length];
                for (int i = 0; i < res.Length; i++)
                {
                    res[i] = encoder.DecodeValue(array[i].Value);
                }
                return(res);
            }
示例#16
0
        public static List <TStorage> EncodeValues <TValue, TStorage>([NotNull] this IValueEncoder <TValue, TStorage> encoder, [NotNull, InstantHandle] IEnumerable <TValue> values)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(values, nameof(values));

            if (values is ICollection <TValue> coll)
            {
                var res = new List <TStorage>(coll.Count);
                foreach (var value in values)
                {
                    res.Add(encoder.EncodeValue(value));
                }
                return(res);
            }

            return(values.Select(encoder.EncodeValue).ToList());
        }
示例#17
0
        public static List <TStorage> EncodeValues <TValue, TStorage, TElement>([NotNull] this IValueEncoder <TValue, TStorage> encoder, [NotNull, InstantHandle] IEnumerable <TElement> items, [NotNull, InstantHandle] Func <TElement, TValue> selector)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(items, nameof(items));
            Contract.NotNull(selector, nameof(selector));

            if (items is ICollection <TElement> coll)
            {
                var res = new List <TStorage>(coll.Count);
                foreach (var item in items)
                {
                    res.Add(encoder.EncodeValue(selector(item)));
                }
                return(res);
            }

            return(items.Select(item => encoder.EncodeValue(selector(item))).ToList());
        }
示例#18
0
        /// <summary>Create a new queue using either High Contention mode or Simple mode</summary>
        /// <param name="subspace">Subspace where the queue will be stored</param>
        /// <param name="highContention">If true, uses High Contention Mode (lots of popping clients). If true, uses the Simple Mode (a few popping clients).</param>
        public FdbQueue([NotNull] FdbSubspace subspace, bool highContention, [NotNull] IValueEncoder <T> encoder)
        {
            if (subspace == null)
            {
                throw new ArgumentNullException("subspace");
            }
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }

            this.Subspace       = subspace;
            this.HighContention = highContention;
            this.Encoder        = encoder;

            this.ConflictedPop  = subspace.Partition(Slice.FromAscii("pop"));
            this.ConflictedItem = subspace.Partition(Slice.FromAscii("conflict"));
            this.QueueItem      = subspace.Partition(Slice.FromAscii("item"));
        }
        /// <summary>Create a new High Contention counter, using a specific value encoder.</summary>
        /// <param name="db">Database used by this layer</param>
        /// <param name="subspace">Subspace to be used for storing the counter</param>
        /// <param name="encoder">Encoder for the counter values</param>
        public FdbHighContentionCounter(IFdbDatabase db, FdbSubspace subspace, IValueEncoder <long> encoder)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }
            if (subspace == null)
            {
                throw new ArgumentNullException("subspace");
            }
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }

            this.Database = db;
            this.Subspace = subspace;
            this.Encoder  = encoder;
        }
        public static T[] DecodeRange <T>(this IValueEncoder <T> encoder, KeyValuePair <Slice, Slice>[] items)
        {
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }

            var values = new T[items.Length];

            for (int i = 0; i < items.Length; i++)
            {
                values[i] = encoder.DecodeValue(items[i].Value);
            }

            return(values);
        }
        public static T[] DecodeRange <T>(this IValueEncoder <T> encoder, Slice[] slices)
        {
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (slices == null)
            {
                throw new ArgumentNullException("slices");
            }

            var values = new T[slices.Length];

            for (int i = 0; i < slices.Length; i++)
            {
                values[i] = encoder.DecodeValue(slices[i]);
            }

            return(values);
        }
        public static Slice[] EncodeRange <T>(this IValueEncoder <T> encoder, [NotNull] T[] values)
        {
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            var slices = new Slice[values.Length];

            for (int i = 0; i < values.Length; i++)
            {
                slices[i] = encoder.EncodeValue(values[i]);
            }

            return(slices);
        }
        /// <summary>Create a new queue using either High Contention mode or Simple mode</summary>
        /// <param name="subspace">Subspace where the queue will be stored</param>
        /// <param name="highContention">If true, uses High Contention Mode (lots of popping clients). If true, uses the Simple Mode (a few popping clients).</param>
        public FdbQueue([NotNull] IFdbSubspace subspace, bool highContention, [NotNull] IValueEncoder <T> encoder)
        {
            if (subspace == null)
            {
                throw new ArgumentNullException("subspace");
            }
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }

            this.Subspace       = subspace.Using(TypeSystem.Tuples);
            this.HighContention = highContention;
            this.Encoder        = encoder;

            //TODO: rewrite this, using FdbEncoderSubpsace<..> !
            this.ConflictedPop  = this.Subspace.Partition.ByKey(Slice.FromAscii("pop"));
            this.ConflictedItem = this.Subspace.Partition.ByKey(Slice.FromAscii("conflict"));
            this.QueueItem      = this.Subspace.Partition.ByKey(Slice.FromAscii("item"));
        }
        /// <summary>Decode an array of slices into an array of <see cref="Optional{T}"/></summary>
        /// <typeparam name="T">Type of the decoded values</typeparam>
        /// <param name="decoder">Decoder used to produce the values</param>
        /// <param name="data">Array of slices to decode. Entries equal to <see cref="Slice.Nil"/> will not be decoded and returned as an empty optional.</param>
        /// <returns>Array of decoded <see cref="Optional{T}"/>.</returns>
        public static Optional <T>[] DecodeRange <T>(IValueEncoder <T> decoder, Slice[] data)
        {
            if (decoder == null)
            {
                throw new ArgumentNullException("decoder");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var values = new Optional <T> [data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                Slice item;
                if ((item = data[i]).HasValue)
                {
                    values[i] = new Optional <T>(decoder.DecodeValue(item));
                }
            }
            return(values);
        }
        public static IEnumerable <Slice> EncodeValues <T>([NotNull] this IValueEncoder <T> encoder, [NotNull] IEnumerable <T> values)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(values, nameof(values));

            // note: T=>Slice usually is used for writing batches as fast as possible, which means that keys will be consumed immediately and don't need to be streamed

            if (values is T[] array)
            {             // optimized path for arrays
                return(EncodeValues <T>(encoder, array));
            }

            if (values is ICollection <T> coll)
            {             // optimized path when we know the count
                var slices = new List <Slice>(coll.Count);
                foreach (var value in coll)
                {
                    slices.Add(encoder.EncodeValue(value));
                }
                return(slices);
            }

            return(values.Select(value => encoder.EncodeValue(value)));
        }
示例#26
0
        public static IEnumerable <TStorage> SelectValues <TValue, TStorage, TElement>([NotNull] this IValueEncoder <TValue, TStorage> encoder, [NotNull] IEnumerable <TElement> items, [NotNull] Func <TElement, TValue> selector)
        {
            Contract.NotNull(encoder, nameof(encoder));
            Contract.NotNull(items, nameof(items));
            Contract.NotNull(selector, nameof(selector));

            return(items.Select(item => encoder.EncodeValue(selector(item))));
        }
示例#27
0
        // from https://apple.github.io/foundationdb/vector.html

        // Vector stores each of its values using its index as the key.
        // The size of a vector is equal to the index of its last key + 1.
        //
        // For indexes smaller than the vector's size that have no associated key
        // in the database, the value will be the specified defaultValue.
        //
        // If the last value in the vector has the default value, its key will
        // always be set so that size can be determined.
        //
        // By creating Vector with a Subspace, all kv pairs modified by the
        // layer will have keys that start within that Subspace.

        // Implementation note:
        // - vector.py uses Thread Local Storage that does not work well with async and Tasks in .NET
        //   so we wont be able to 'store' the current transaction in the vector object itself

        /// <summary>Create a new sparse Vector</summary>
        /// <param name="location">Subspace where the vector will be stored</param>
        /// <param name="defaultValue">Default value for sparse entries</param>
        /// <param name="encoder">Encoder used for the values of this vector</param>
        public FdbVector(ISubspaceLocation location, T defaultValue = default, IValueEncoder <T>?encoder = null)
            : this(location.AsDynamic(), defaultValue, encoder)
        {
        }
示例#28
0
 internal State(IDynamicKeySubspace subspace, T defaultValue, IValueEncoder <T> encoder)
 {
     this.Subspace     = subspace;
     this.DefaultValue = defaultValue;
     this.Encoder      = encoder;
 }
		public FdbDocumentCollection(ITypedKeySubspace<TId, int> subspace, Func<TDocument, TId> selector, IValueEncoder<TDocument> valueEncoder)
		{
			if (subspace == null) throw new ArgumentNullException(nameof(subspace));
			if (selector == null) throw new ArgumentNullException(nameof(selector));
			if (valueEncoder == null) throw new ArgumentNullException(nameof(valueEncoder));

			this.Subspace = subspace;
			this.IdSelector = selector;
			this.ValueEncoder = valueEncoder;
		}
        /// <summary>Create a new queue using either High Contention mode or Simple mode</summary>
        /// <param name="subspace">Subspace where the queue will be stored</param>
        /// <param name="highContention">If true, uses High Contention Mode (lots of popping clients). If true, uses the Simple Mode (a few popping clients).</param>
        /// <param name="encoder">Encoder for the values stored in this queue</param>
        public FdbQueue([NotNull] IDynamicKeySubspace subspace, bool highContention = false, IValueEncoder <T> encoder = null)
        {
            if (subspace == null)
            {
                throw new ArgumentNullException(nameof(subspace));
            }

            this.Subspace       = subspace;
            this.HighContention = highContention;
            this.Encoder        = encoder ?? TuPack.Encoding.GetValueEncoder <T>();

            //TODO: rewrite this, using FdbEncoderSubpsace<..> !
            this.ConflictedPop  = this.Subspace.Partition.ByKey(Slice.FromStringAscii("pop"));
            this.ConflictedItem = this.Subspace.Partition.ByKey(Slice.FromStringAscii("conflict"));
            this.QueueItem      = this.Subspace.Partition.ByKey(Slice.FromStringAscii("item"));
        }
		public const int DefaultChunkSize = 1 << 20; // 1 MB

		public FdbDocumentCollection(IKeySubspace subspace, Func<TDocument, TId> selector, IValueEncoder<TDocument> valueEncoder)
			: this(subspace.AsTyped<TId, int>(), selector, valueEncoder)
		{ }