private void MergeBlocks(List <IEnumerator <Record> > blockRecordsEnumerators, BufferedRecordsWriter recordsWriter, int field) { IRecordFieldComparer comparer = _recordComparer.CreateRecordFieldComparer(field); var currentRecordComparer = new SelectComparer <int, Record>( i => blockRecordsEnumerators[i].Current, comparer); var heap = new MinHeap <int>(blockRecordsEnumerators.Count, currentRecordComparer); for (int i = 0; i < blockRecordsEnumerators.Count; i++) { blockRecordsEnumerators[i].MoveNext(); heap.Add(i); } while (heap.Size > 0) { recordsWriter.WriteRecord(blockRecordsEnumerators[heap.Root].Current); bool empty = !blockRecordsEnumerators[heap.Root].MoveNext(); if (empty) { heap.Extract(); } else { heap.DownHeap(); } } }
private static List <T> Merge <T>(List <T> list, int chunkCount, int chunkSize, IComparer <T> comparer) { int[] chunkIndexes = new int[chunkCount]; int[] chunkEnds = new int[chunkCount]; for (int i = 0; i < chunkCount; i++) { chunkIndexes[i] = i * chunkSize; chunkEnds[i] = i * chunkSize + chunkSize; } chunkEnds[chunkEnds.Length - 1] = list.Count; MinHeap <int> heap = new MinHeap <int>(chunkCount, new SelectComparer <int, T>(i => list[chunkIndexes[i]], comparer)); for (int i = 0; i < chunkCount; i++) { heap.Add(i); } List <T> result = new List <T>(list.Count); for (int i = 0; i < list.Count; i++) { result.Add(list[chunkIndexes[heap.Root]]); chunkIndexes[heap.Root]++; if (chunkIndexes[heap.Root] == chunkEnds[heap.Root]) { heap.Extract(); } else { heap.DownHeap(); } } return(result); }