/// <summary> /// Create a new object representing a binary large object (blob). /// Only keys within the subspace will be used by the object. /// Other clients of the database should refrain from modifying the subspace.</summary> /// <param name="location">Subspace to be used for storing the blob data and metadata</param> public FdbBlob(ISubspaceLocation location) { if (location == null) { throw new ArgumentNullException(nameof(location)); } this.Location = location.AsDynamic(); }
protected async Task DumpSubspace(IFdbReadOnlyTransaction tr, ISubspaceLocation location) { var subspace = await location.Resolve(tr); if (subspace != null) { await TestHelpers.DumpSubspace(tr, subspace); } else { Log($"# Location {location} not found!"); } }
public static async Task CleanLocation(IFdbDatabase db, ISubspaceLocation location, CancellationToken ct) { Assert.That(db, Is.Not.Null, "null db"); if (location.Path.Count == 0 && location.Prefix.Count == 0) { Assert.Fail("Cannot clean the root of the database!"); } // if the prefix part is empty, then we simply recursively remove the corresponding sub-directory tree // If it is not empty, we only remove the corresponding subspace (without touching the sub-directories!) await db.WriteAsync(async tr => { tr.StopLogging(); if (location.Path.Count == 0) { // subspace under the root of the partition // get and clear subspace tr.ClearRange(KeyRange.StartsWith(location.Prefix)); } else if (location.Prefix.Count == 0) { // remove previous await db.DirectoryLayer.TryRemoveAsync(tr, location.Path); // create new _ = await db.DirectoryLayer.CreateAsync(tr, location.Path); } else { // subspace under a directory subspace // make sure the parent path exists! var subspace = await db.DirectoryLayer.CreateOrOpenAsync(tr, location.Path); // get and clear subspace tr.ClearRange(subspace.Partition[location.Prefix].ToRange()); } }, ct); }
public static async Task DumpLocation(IFdbDatabase db, ISubspaceLocation path, CancellationToken ct) { Assert.That(db, Is.Not.Null); using (var tr = await db.BeginTransactionAsync(ct)) { tr.StopLogging(); var subspace = await path.Resolve(tr); if (subspace == null) { FdbTest.Log($"Dumping content of subspace {path}:"); FdbTest.Log("> EMPTY!"); return; } await DumpSubspace(tr, subspace).ConfigureAwait(false); if (path.Prefix.Count == 0) { var names = await db.DirectoryLayer.TryListAsync(tr, path.Path); if (names != null) { foreach (var name in names) { var child = await db.DirectoryLayer.TryOpenAsync(tr, path.Path[name]); if (child != null) { await DumpSubspace(tr, child); } } } } } }
// 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) { }
private const int LEVEL_FAN_POW = 4; // 2^X per level public FdbRankedSet(ISubspaceLocation location) : this(location?.AsDynamic()) { }
protected Task DumpSubspace(IFdbDatabase db, ISubspaceLocation path) { return(TestHelpers.DumpLocation(db, path, this.Cancellation)); }
protected Task CleanLocation(IFdbDatabase db, ISubspaceLocation location) { return(TestHelpers.CleanLocation(db, location, this.Cancellation)); }
public const int DefaultChunkSize = 1 << 20; // 1 MB public FdbDocumentCollection(ISubspaceLocation subspace, Func <TDocument, TId> selector, IValueEncoder <TDocument> valueEncoder) : this(subspace.AsTyped <TId, int>(), selector, valueEncoder) { }
/// <summary>Create an allocator operating under a specific location</summary> public FdbHighContentionAllocator(ISubspaceLocation location) { Contract.NotNull(location); this.Location = location.AsTyped <int, long>(); }
// Inspired by https://apple.github.io/foundationdb/multimaps.html // It is the logical equivalent of a Map<KeyValuePair<TKey, TValue>, long> where the value would be incremented each time a specific pair of (key, value) is added (and subtracted when removed) // The layer stores each key/value using the following format: // (..., key, value) = 64-bit counter /// <summary>Create a new multimap</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> public FdbMultiMap(ISubspaceLocation subspace, bool allowNegativeValues) : this(subspace.AsTyped <TKey, TValue>(), allowNegativeValues) { }
/// <summary>Create a new High Contention counter.</summary> /// <param name="location">Subspace to be used for storing the counter</param> public FdbHighContentionCounter(ISubspaceLocation location) : this(location.AsDynamic(), TuPack.Encoding.GetValueEncoder <long>()) { }
public FdbMap(ISubspaceLocation location, IValueEncoder <TValue> valueEncoder) : this(location.AsTyped <TKey>(), valueEncoder) { }
/// <summary>Create a new queue using either High Contention mode or Simple mode</summary> /// <param name="location">Subspace where the queue will be stored</param> /// <param name="encoder">Encoder for the values stored in this queue</param> /// <remarks>Uses the default Tuple serializer</remarks> public FdbQueue(ISubspaceLocation location, IValueEncoder <T>?encoder = null) : this(location.AsTyped <VersionStamp>(), encoder) { }
public FdbIndex(ISubspaceLocation path, IEqualityComparer <TValue>?valueComparer = null, bool indexNullValues = false) : this(path.AsTyped <TValue, TId>(), valueComparer, indexNullValues) { }
public bool Equals(ISubspaceLocation other) { return(other != null && other.Path == this.Path && other.Prefix.Count == 0); }