private async Task <Slice> GetPreviousNodeAsync(IFdbTransaction trans, int level, Slice key) { // GetPreviousNodeAsync looks for the previous node on a level, but "doesn't care" // about the contents of that node. It therefore uses a non-isolated (snaphot) // read and explicitly adds a conflict range that is exclusive of the actual, // found previous node. This allows an increment of that node not to trigger // a transaction conflict. We also add a conflict key on the found previous // key in level 0. This allows detection of erasures. var k = this.Subspace.Encode(level, key); //Console.WriteLine(k); //Console.WriteLine("GetPreviousNode(" + level + ", " + key + ")"); //Console.WriteLine(KeySelector.LastLessThan(k) + " <= x < " + KeySelector.FirstGreaterOrEqual(k)); var kv = await trans .Snapshot .GetRange( KeySelector.LastLessThan(k), KeySelector.FirstGreaterOrEqual(k) ) .FirstAsync() .ConfigureAwait(false); //Console.WriteLine("Found " + FdbKey.Dump(kv.Key)); var prevKey = this.Subspace.DecodeLast <Slice>(kv.Key); trans.AddReadConflictRange(kv.Key + FdbKey.MinValue, k); trans.AddReadConflictKey(this.Subspace.Encode(0, prevKey)); return(prevKey); }
private async Task <long> GetNextIndexAsync([NotNull] IFdbReadOnlyTransaction tr, IFdbDynamicSubspace subspace) { var range = subspace.Keys.ToRange(); var lastKey = await tr.GetKeyAsync(KeySelector.LastLessThan(range.End)).ConfigureAwait(false); if (lastKey < range.Begin) { return(0); } return(subspace.Keys.DecodeFirst <long>(lastKey) + 1); }
private async Task PushQueueAsync(IFdbTransaction tr, IDynamicKeySubspace queue, Slice taskId) { //TODO: use a high contention algo ? // - must support Push and Pop // - an empty queue must correspond to an empty subspace // get the current size of the queue var range = queue.Keys.ToRange(); var lastKey = await tr.Snapshot.GetKeyAsync(KeySelector.LastLessThan(range.End)).ConfigureAwait(false); int count = lastKey < range.Begin ? 0 : queue.Keys.DecodeFirst <int>(lastKey) + 1; // set the value tr.Set(queue.Keys.Encode(count, GetRandomId()), taskId); }
public async void Test_Case_11() { using (var zedb = await OpenTestDatabaseAsync()) { var db = FoundationDB.Filters.Logging.FdbLoggingExtensions.Logged(zedb, (tr) => Log(tr.Log.GetTimingsReport(true))); { var subspace = db.GlobalSpace; // clear everything and write some values await db.WriteAsync((tr) => { tr.ClearRange(subspace.Keys.Encode("K0000"), subspace.Keys.Encode("K9999Z")); for (int i = 0; i < 100; i++) { tr.Set(subspace.Keys.Encode("K" + i.ToString("D4")), Slice.FromString("V" + i.ToString("D4"))); } }, this.Cancellation); using (var tr = db.BeginTransaction(this.Cancellation)) { tr.ClearRange(subspace.Keys.Encode("K0010"), subspace.Keys.Encode("K0020")); tr.ClearRange(subspace.Keys.Encode("K0050"), subspace.Keys.Encode("K0060")); tr.Set(subspace.Keys.Encode("K0021"), Slice.Empty); tr.Set(subspace.Keys.Encode("K0042"), Slice.Empty); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0005"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0010"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0015"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0022"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0049"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0050"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0055"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0061"))); //no commit } using (var tr = db.BeginTransaction(this.Cancellation)) { //tr.SetOption(FdbTransactionOption.ReadYourWritesDisable); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0000"))); // equal=false, offset=1 await tr.GetKeyAsync(KeySelector.FirstGreaterThan(subspace.Keys.Encode("K0011"))); // equal=true, offset=1 await tr.GetKeyAsync(KeySelector.LastLessOrEqual(subspace.Keys.Encode("K0022"))); // equal=true, offset=0 await tr.GetKeyAsync(KeySelector.LastLessThan(subspace.Keys.Encode("K0033"))); // equal=false, offset=0 await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Keys.Encode("K0040")) + 1000); // equal=false, offset=7 ? await tr.GetKeyAsync(KeySelector.LastLessThan(subspace.Keys.Encode("K0050")) + 1000); // equal=false, offset=6 ? } } } }
public async Task Test_Case_11() { using (var db = await OpenTestPartitionAsync()) { db.SetDefaultLogHandler((log) => Log(log.GetTimingsReport(true))); var location = db.Root; // clear everything and write some values await db.WriteAsync(async tr => { var subspace = await location.Resolve(tr); tr.ClearRange(subspace.Encode("K0000"), subspace.Encode("K9999Z")); for (int i = 0; i < 100; i++) { tr.Set(subspace.Encode("K" + i.ToString("D4")), Value("V" + i.ToString("D4"))); } }, this.Cancellation); using (var tr = await db.BeginTransactionAsync(this.Cancellation)) { var subspace = await location.Resolve(tr); tr.ClearRange(subspace.Encode("K0010"), subspace.Encode("K0020")); tr.ClearRange(subspace.Encode("K0050"), subspace.Encode("K0060")); tr.Set(subspace.Encode("K0021"), Slice.Empty); tr.Set(subspace.Encode("K0042"), Slice.Empty); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0005"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0010"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0015"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0022"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0049"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0050"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0055"))); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0061"))); //no commit } using (var tr = await db.BeginTransactionAsync(this.Cancellation)) { var subspace = await location.Resolve(tr); //tr.SetOption(FdbTransactionOption.ReadYourWritesDisable); await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0000"))); // equal=false, offset=1 await tr.GetKeyAsync(KeySelector.FirstGreaterThan(subspace.Encode("K0011"))); // equal=true, offset=1 await tr.GetKeyAsync(KeySelector.LastLessOrEqual(subspace.Encode("K0022"))); // equal=true, offset=0 await tr.GetKeyAsync(KeySelector.LastLessThan(subspace.Encode("K0033"))); // equal=false, offset=0 await tr.GetKeyAsync(KeySelector.FirstGreaterOrEqual(subspace.Encode("K0040")) + 1000); // equal=false, offset=7 ? await tr.GetKeyAsync(KeySelector.LastLessThan(subspace.Encode("K0050")) + 1000); // equal=false, offset=6 ? } } }