public async Task Test_FdbMap_With_Custom_Key_Encoder() { // Use a table as a backing store for the rules of a Poor Man's firewall, where each keys are the IPEndPoint (tcp only!), and the values are "pass" or "block" // Encode IPEndPoint as the (IP, Port,) encoded with the Tuple codec // note: there is a much simpler way or creating composite keys, this is just a quick and dirty test! var keyEncoder = KeyValueEncoders.Bind <IPEndPoint>( (ipe) => ipe == null ? Slice.Empty : FdbTuple.EncodeKey(ipe.Address, ipe.Port), (packed) => { if (packed.IsNullOrEmpty) { return(default(IPEndPoint)); } var t = FdbTuple.Unpack(packed); return(new IPEndPoint(t.Get <IPAddress>(0), t.Get <int>(1))); } ); var rules = new Dictionary <IPEndPoint, string>() { { new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667), "block" }, { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 80), "pass" }, { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443), "pass" } }; using (var db = await OpenTestPartitionAsync()) { var location = await GetCleanDirectory(db, "Collections", "Maps"); var map = new FdbMap <IPEndPoint, string>("Firewall", location.Partition.ByKey("Hosts"), keyEncoder, KeyValueEncoders.Values.StringEncoder); // import all the rules await db.WriteAsync((tr) => { foreach (var rule in rules) { map.Set(tr, rule.Key, rule.Value); } }, this.Cancellation); #if DEBUG await DumpSubspace(db, location); #endif // test the rules using (var tr = db.BeginTransaction(this.Cancellation)) { var value = await map.GetAsync(tr, new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667)); Assert.That(value, Is.EqualTo("block")); value = await map.GetAsync(tr, new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443)); Assert.That(value, Is.EqualTo("pass")); var baz = new IPEndPoint(IPAddress.Parse("172.16.12.34"), 80); Assert.That(async() => await map.GetAsync(tr, baz), Throws.InstanceOf <KeyNotFoundException>()); var opt = await map.TryGetAsync(tr, baz); Assert.That(opt.HasValue, Is.False); } } }
public async Task Test_Range_Except() { int K = 3; int N = 100; using (var db = await OpenTestPartitionAsync()) { // get a clean new directory var location = await GetCleanDirectory(db, "Queries", "Except"); // create K lists var lists = Enumerable.Range(0, K).Select(i => location.Partition.ByKey(i)).ToArray(); // lists[0] contains all multiples of 1 // lists[1] contains all multiples of 2 // lists[k-1] contains all multiples of K // more generally: lists[k][i] = (..., Intersect, k, i * (k + 1)) = (k, i) var series = Enumerable.Range(1, K).Select(k => Enumerable.Range(1, N).Select(x => k * x).ToArray()).ToArray(); //foreach(var serie in series) //{ // Console.WriteLine(String.Join(", ", serie)); //} for (int k = 0; k < K; k++) { //Console.WriteLine("> k = " + k); using (var tr = db.BeginTransaction(this.Cancellation)) { for (int i = 0; i < N; i++) { var key = lists[k].Keys.Encode(series[k][i]); var value = FdbTuple.EncodeKey(k, i); //Console.WriteLine("> " + key + " = " + value); tr.Set(key, value); } await tr.CommitAsync(); } } // Intersect all lists together should produce all integers that are prime numbers IEnumerable <int> xs = series[0]; for (int i = 1; i < K; i++) { xs = xs.Except(series[i]); } var expected = xs.ToArray(); Log("Expected: {0}", String.Join(", ", expected)); using (var tr = db.BeginTransaction(this.Cancellation)) { var merge = tr.Except( lists.Select(list => FdbKeySelectorPair.Create(list.Keys.ToRange())), kvp => location.Keys.DecodeLast <int>(kvp.Key) ); Assert.That(merge, Is.Not.Null); Assert.That(merge, Is.InstanceOf <FdbExceptIterator <KeyValuePair <Slice, Slice>, int, KeyValuePair <Slice, Slice> > >()); var results = await merge.ToListAsync(); Assert.That(results, Is.Not.Null); Assert.That(results.Count, Is.EqualTo(expected.Length)); for (int i = 0; i < results.Count; i++) { Assert.That(location.Keys.DecodeLast <int>(results[i].Key), Is.EqualTo(expected[i])); } } } }
public Slice EncodeValue(T key) { return(FdbTuple.EncodeKey(key)); }