/// <summary>Create a new counter map, using a specific key encoder.</summary> public FdbCounterMap(ITypedKeySubspace <TKey> subspace) { Contract.NotNull(subspace, nameof(subspace)); this.Subspace = subspace; this.Location = subspace; }
/// <summary>Create a new multimap, using a specific key and value encoder</summary> /// <param name="subspace">Location where the map will be stored in the database</param> /// <param name="allowNegativeValues">If true, allow negative or zero values to stay in the map.</param> /// <param name="encoder">Encoder for the key/value pairs</param> public FdbMultiMap(ITypedKeySubspace<TKey, TValue> subspace, bool allowNegativeValues) { if (subspace == null) throw new ArgumentNullException(nameof(subspace)); this.AllowNegativeValues = allowNegativeValues; this.Subspace = subspace; }
protected virtual Task <List <Slice> > LoadPartsAsync(ITypedKeySubspace <TId, int> subspace, IFdbReadOnlyTransaction trans, TId id) { var key = subspace.EncodePartial(id); return(trans .GetRange(KeyRange.StartsWith(key)) //TODO: options ? .Select(kvp => kvp.Value) .ToListAsync()); }
/// <summary>Create a new counter map, using a specific key encoder.</summary> public FdbCounterMap([NotNull] ITypedKeySubspace <TKey> subspace) { if (subspace == null) { throw new ArgumentNullException(nameof(subspace)); } this.Subspace = subspace; this.Location = subspace; }
public FdbCompressedBitmapIndex(string name, ITypedKeySubspace <TValue> subspace, IEqualityComparer <TValue>?valueComparer = null, bool indexNullValues = false) { Contract.NotNull(name); Contract.NotNull(subspace); this.Name = name; this.Subspace = subspace; this.ValueComparer = valueComparer ?? EqualityComparer <TValue> .Default; this.IndexNullValues = indexNullValues; }
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; }
public FdbIndex([NotNull] string name, [NotNull] ITypedKeySubspace <TValue, TId> subspace, IEqualityComparer <TValue> valueComparer, bool indexNullValues) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (subspace == null) { throw new ArgumentNullException(nameof(subspace)); } this.Name = name; this.Subspace = subspace; this.ValueComparer = valueComparer ?? EqualityComparer <TValue> .Default; this.IndexNullValues = indexNullValues; }
public FdbMap([NotNull] string name, [NotNull] ITypedKeySubspace <TKey> subspace, [NotNull] IValueEncoder <TValue> valueEncoder) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (subspace == null) { throw new ArgumentNullException(nameof(subspace)); } if (valueEncoder == null) { throw new ArgumentNullException(nameof(valueEncoder)); } this.Name = name; this.Subspace = subspace; this.ValueEncoder = valueEncoder; }
public static Slice Pack <T1>(this ITypedKeySubspace <T1> self, ValueTuple <T1> tuple) { return(self.Encode(tuple.Item1)); }
public static KeyRange EncodeRange <T1>(this ITypedKeySubspace <T1> self, [AllowNull] T1 item1) { //TODO: add concept of "range" on IKeyEncoder ? return(KeyRange.PrefixedBy(self.Encode(item1))); }
public static KeyRange PackRange <T1>(this ITypedKeySubspace <T1> self, ValueTuple <T1> tuple) { return(KeyRange.PrefixedBy(self.Encode(tuple.Item1))); }
public static TypedKeySubspace <T1, T2, T3, T4> Copy <T1, T2, T3, T4>(this ITypedKeySubspace <T1, T2, T3, T4> subspace, ISubspaceContext?context = null) { Contract.NotNull(subspace); return(new TypedKeySubspace <T1, T2, T3, T4>(StealPrefix(subspace), subspace.KeyEncoder, context ?? subspace.Context)); }
public State(ITypedKeySubspace <VersionStamp> subspace, IValueEncoder <T> encoder) { this.Subspace = subspace; this.Encoder = encoder; }
internal State(ITypedKeySubspace <TKey, TValue> subspace, bool allowNegativeValues) { this.Subspace = subspace; this.AllowNegativeValues = allowNegativeValues; }
public State(FdbIndex <TId, TValue> schema, ITypedKeySubspace <TValue, TId> subspace) { this.Schema = schema; this.Subspace = subspace; }
public static IEnumerable <Slice> Encode <T1>(this ITypedKeySubspace <T1> self, IEnumerable <T1> items) { return(self.KeyEncoder.EncodeKeys(self.GetPrefix(), items)); }
public static TypedKeySubspace <T1, T2, T3, T4> Copy <T1, T2, T3, T4>([NotNull] this ITypedKeySubspace <T1, T2, T3, T4> subspace) { Contract.NotNull(subspace, nameof(subspace)); return(new TypedKeySubspace <T1, T2, T3, T4>(StealPrefix(subspace), subspace.KeyEncoder)); }
public static Slice Pack <T1, TTuple>(this ITypedKeySubspace <T1> self, TTuple tuple) where TTuple : IVarTuple { return(self.Encode(tuple.OfSize(1).Get <T1>(0))); }
public State(ITypedKeySubspace <int, long> subspace, Random rng) { this.Subspace = subspace; this.Rng = rng; }
public static Slice[] Encode <T1>(this ITypedKeySubspace <T1> self, params T1[] items) { return(self.KeyEncoder.EncodeKeys(self.GetPrefix(), items)); }
internal State(ITypedKeySubspace <TKey> subspace, IValueEncoder <TValue> encoder) { Contract.Requires(subspace != null && encoder != null); this.Subspace = subspace; this.ValueEncoder = encoder; }
/// <summary>Decode a key from this subspace back into a value</summary> public static void Decode <T1>(this ITypedKeySubspace <T1> self, Slice packedKey, [MaybeNull] out T1 item1) { item1 = self.Decode(packedKey) !; }
public static async Task <long> AllocateAsync(IFdbTransaction trans, ITypedKeySubspace <int, long> subspace, Random rng) { Contract.NotNull(trans); // find the current window size, by reading the last entry in the 'counters' subspace long start = 0, count = 0; var kv = await trans .Snapshot .GetRange(subspace.EncodePartialRange(COUNTERS)) .LastOrDefaultAsync(); if (kv.Key.Count != 0) { start = subspace.DecodeLast(kv.Key); count = kv.Value.ToInt64(); } // check if the window is full int window = GetWindowSize(start); if ((count + 1) * 2 >= window) { // advance the window if (FdbDirectoryLayer.AnnotateTransactions) { trans.Annotate("Advance allocator window size to {0} starting at {1}", window, start + window); } trans.ClearRange(subspace[COUNTERS, 0], subspace[COUNTERS, start + 1]); start += window; count = 0; trans.ClearRange(subspace[RECENT, 0], subspace[RECENT, start]); } // Increment the allocation count for the current window trans.AtomicAdd64(subspace[COUNTERS, start], 1); // As of the snapshot being read from, the window is less than half // full, so this should be expected to take 2 tries. Under high // contention (and when the window advances), there is an additional // subsequent risk of conflict for this transaction. while (true) { // Find a random free slot in the current window... long candidate; lock (rng) { candidate = start + rng.Next(window); } // test if the key is used var key = subspace[RECENT, candidate]; var value = await trans.GetAsync(key).ConfigureAwait(false); if (value.IsNull) { // free slot // mark as used trans.Set(key, Slice.Empty); if (FdbDirectoryLayer.AnnotateTransactions) { trans.Annotate("Allocated prefix {0} from window [{1}..{2}] ({3} used)", candidate, start, start + window - 1, count + 1); } return(candidate); } // no luck this time, try again... } }