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); }
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); }