public async Task WithinPartition_by_range_correctly_partitions_queries_by_guid() { var id = Guid.NewGuid().ToString(); await WriteEvents(i => new Event { SequenceNumber = i, Id = id }); var stream = Stream.PartitionedByRange <Event, int, Guid>(async(q, p) => { using (var db = new AlluvialSqlTestsDbContext()) { return(await db.Events .Where(e => e.Id == id) .WithinPartition(e => e.Guid, p) .ToArrayAsync()); } }); var catchup = stream.DistributeAmong(Partition.AllGuids().Among(20)); var store = new InMemoryProjectionStore <int>(); catchup.Subscribe(async(count, events) => events.Count, store); await catchup.RunSingleBatch(); store.Sum(e => e).Should().Be(100); }
public async Task GuidQueryPartitioner_partitions_guids_fairly() { var totalNumberOfGuids = 1000; var numberOfPartitions = 50; var partitions = Partition.AllGuids() .Among(numberOfPartitions); var guids = Enumerable.Range(1, totalNumberOfGuids).Select(_ => Guid.NewGuid()).ToArray(); var partitioned = Stream.Partitioned <Guid, int, Guid>( async(q, p) => guids.Where(g => g.IsWithinPartition(p)), advanceCursor: (q, b) => q.Cursor.AdvanceTo(totalNumberOfGuids)); var aggregator = Aggregator.Create <Projection <HashSet <Guid>, int>, Guid>((p, b) => { if (p.Value == null) { p.Value = new HashSet <Guid>(); } foreach (var guid in b) { p.Value.Add(guid); } }); var store = new InMemoryProjectionStore <Projection <HashSet <Guid>, int> >(); await Task.WhenAll(partitions.Select(async partition => { var stream = await partitioned.GetStream(partition); var catchup = StreamCatchup.Create(stream, batchSize: int.MaxValue); catchup.Subscribe(aggregator, store); await catchup.RunSingleBatch(); var projection = await store.Get(stream.Id); Console.WriteLine(partition + ": " + projection.Value.Count); })); var approximateGuidsPerPartition = totalNumberOfGuids / numberOfPartitions; var tolerance = (int)(totalNumberOfGuids * .12); store.Sum(p => p.Value.Count).Should().Be(totalNumberOfGuids); store.ToList().ForEach(projection => { projection.Value .Count .Should() .BeInRange(approximateGuidsPerPartition - tolerance, approximateGuidsPerPartition + tolerance); }); }
public async Task Guid_partitions_as_integers_are_gapless() { int numberOfPartitions = 1000; var partitions = Partition.AllGuids() .Among(numberOfPartitions) .ToArray(); for (var i = 0; i < numberOfPartitions - 1; i++) { var firstPartition = partitions[i]; var secondPartition = partitions[i + 1]; firstPartition.LowerBoundExclusive.Should().NotBe(firstPartition.UpperBoundInclusive); firstPartition.UpperBoundInclusive .Should() .Be(secondPartition.LowerBoundExclusive); firstPartition.UpperBoundInclusive.ToBigInteger() .Should() .Be(secondPartition.LowerBoundExclusive.ToBigInteger()); } }