private IEnumerable GetReplannedLineup()

in code/KustoCopyConsole/Runner/ExportingRunner.cs [212:268]


        private IEnumerable<BlockRowItem> GetReplannedLineup(
            IEnumerable<BlockRowItem> candidates,
            double targetRowCount,
            int freeCapacity)
        {
            //  Stack them upside down
            var candidateStack =
                new Stack<BlockRowItem>(candidates.OrderByDescending(c => c.IngestionTimeStart));
            var lineup = new List<BlockRowItem>(freeCapacity);

            while (freeCapacity - lineup.Count > 0 && candidateStack.Any())
            {
                var first = candidateStack.Pop();

                if (candidateStack.Any())
                {
                    var second = candidateStack.Pop();
                    var merge = new BlockRowItem
                    {
                        State = first.State,
                        ActivityName = first.ActivityName,
                        IterationId = first.IterationId,
                        BlockId = first.BlockId,
                        IngestionTimeStart = first.IngestionTimeStart,
                        IngestionTimeEnd = second.IngestionTimeEnd,
                        MinCreationTime = first.MinCreationTime < second.MinCreationTime
                        ? first.MinCreationTime
                        : second.MinCreationTime,
                        MaxCreationTime = first.MaxCreationTime > second.MaxCreationTime
                        ? first.MaxCreationTime
                        : second.MaxCreationTime,
                        PlannedRowCount = first.PlannedRowCount + second.PlannedRowCount,
                        ReplannedBlockIds = first.ReplannedBlockIds
                        .Concat(second.ReplannedBlockIds)
                        .Append(second.BlockId)
                        .ToImmutableArray(),
                    };

                    if (merge.PlannedRowCount <= targetRowCount
                        && (merge.MaxCreationTime - merge.MinCreationTime < TimeSpan.FromDays(1)))
                    {
                        candidateStack.Push(merge);
                    }
                    else
                    {
                        lineup.Add(first);
                        candidateStack.Push(second);
                    }
                }
                else
                {
                    lineup.Add(first);
                }
            }

            return lineup;
        }