Sortowanie merge sort czy inne ogólnego zastosowania jest wariactwem, gdy masz tak mocno ograniczoną domeną.
Rozumiem, że spodziewasz się, jak rozłożone są dane w tych plikach średnio?
Nie kapuję do końca tej struktury (może przykładzik prawdziwych danych),
ale sugeruję sortowanie kubełkowe. Będzie skrajnie proste do zaimplementowania i otestowania,
wydajne na poziomie O(n) oraz możesz je stosować na częściach (on-demand a nie upfront) i do tego łatwo utrzymywać,
dla przychodzących nowych danych. No i oczywiście działa pięknie strumieniowo, bez przeciążania pamięci.
Żeby wyjaśnić - lecisz plik po pliku i rozrzucasz dane do kubełków, wg przedziałów wartości.
Powiedzmy mam 2 pliki do posortowania:
a.txt:
Ania
Krysia
Helena
b.txt:
Beata
Matylda
Znając dziedzinę (żeńskie imiona), sprawdzam czętości występowań imion (u Ciebie to by były zagęszczenia lokalizacji)
i dzielę na odpowiednią ilość kubełków (koniecznie, aby liczba kubełków ~ O(n), a w kubełku < K elementow, dla pewnego K.
Powiedzmy u nas to kubełki A-K i N-Z i otrzymujemy pliki:
A-K.txt:
Ania
Krysia
Helena
Beata
N-Z.txt
Matylda
Wtedy sortujesz już pliki rozmiarów <K (łatwo załadować do pamięci i użyć dowolnego zastowoania).
Oczywiście można to zrobić w czasie pierwszego użycia danych.
To wymaga mało kodowania, ale posiedzenia z kartką i ołówkiem, aby poznać dziedzinę i dobrać kubełki.
Jeśli imion miałbym 5GB, to kubełki dzieliłbym np wg prefixu pierwszych 4 znaków:
AAAA.txt.
AAAB.txt
and so on
Jeśli posortowane dane potrzebne są Ci jako jeden dlugi strumien, nic prostszego:
strumieniujesz: joinIterators(buckets[0].sortedIterator, ..., buckets[N/K].sortedIterator),
gdzie sorted iterator posortuje elementy w kubełku w czasie wyciągania elementów w runtime,
a nie w momencie utworzenia go.
Pozdrawiam,
Wojtek