예제 #1
0
        private int SortBlocksSequential(RecordsReader recordsReader, int field, out RecordsBuffer firstBlock)
        {
            int blockIndex = 0;

            firstBlock = null;
            IEnumerable <RecordsBuffer> blocks = recordsReader.ReadBlocks();

            foreach (RecordsBuffer block in blocks)
            {
                block.Sort(field);
                if (blockIndex == 0)
                {
                    if (recordsReader.IsLastBlock)
                    {
                        firstBlock = block;
                        return(1);
                    }
                }

                WriteBlock(block, blockIndex);
                Console.WriteLine($"Block {blockIndex} sorted");
                blockIndex++;
            }
            return(blockIndex);
        }
예제 #2
0
        private int SortBlocksParallel(RecordsReader recordsReader, int field, int workersCount,
                                       out RecordsBuffer firstBlock)
        {
            firstBlock = null;
            IEnumerator <RecordsBuffer> blocks = recordsReader.ReadBlocks().GetEnumerator();

            if (!blocks.MoveNext())
            {
                return(0);
            }

            if (recordsReader.IsLastBlock)
            {
                firstBlock = blocks.Current;
                firstBlock.Sort(field);
                return(1);
            }

            int blockIndex = 0;

            using (var blockCollection = new BlockingCollection <Tuple <RecordsBuffer, int> >(workersCount))
                using (var sortCompletionCollection = new BlockingCollection <bool>(workersCount))
                {
                    Task blocksReadingTask = Task.Factory.StartNew(() =>
                    {
                        do
                        {
                            blockCollection.Add(new Tuple <RecordsBuffer, int>(blocks.Current, blockIndex++));
                            sortCompletionCollection.Add(true);
                        } while (blocks.MoveNext());
                        blockCollection.CompleteAdding();
                    });

                    Task blocksSortingTask = Task.Factory.StartNew(() =>
                    {
                        List <Task> sortTasks = new List <Task>();
                        try
                        {
                            while (true)
                            {
                                Tuple <RecordsBuffer, int> blockAndIndex = blockCollection.Take();

                                Task t = StartBlockSortingTask(blockAndIndex.Item1, blockAndIndex.Item2,
                                                               field, sortCompletionCollection);
                                sortTasks.Add(t);
                            }
                        }
                        catch (InvalidOperationException)
                        {
                            // An InvalidOperationException means that Take() was called on a completed collection
                        }
                        Task.WaitAll(sortTasks.ToArray());
                    });

                    Task.WaitAll(blocksReadingTask, blocksSortingTask);
                }
            return(blockIndex);
        }