Il grafico non è adatto a questo, l'implementazione richiede più memoria di albero e in questo caso non fornisce alcuna funzionalità aggiuntiva.
Alberi prefisso? Questi sono molto efficienti per la ricerca ma la rappresentazione della memoria non è ottimizzata per le dimensioni. In realtà sono molto inefficienti per la memoria. Possono anche essere utilizzati per comprimere i dati e scriverli sul disco ma la rappresentazione della memoria richiede molta più memoria dei dati stessi.
Se organizzi i gruppi in modo che solo 3 ultime cifre siano memorizzate nella struttura ad albero, sarebbero comunque 3x4 + 1 byte per ogni numero (puntatore 3x4 byte + 1 byte per i dati). ~ 78 GB solo per 3 ultime cifre di ogni numero (se ricordo correttamente i dettagli di implementazione). Quale richiederà 64 puntatori di bit invece di 32b ... quindi ~ 140 GB di ram.
Quindi il problema (secondo me) è che per albero per ogni suffisso in ogni gruppo hai ancora bisogno di almeno un puntatore a 32 bit (che probabilmente si rivelerà essere 64 bit perché avresti bisogno di allocare > 4GB per i dati).
A mio parere il modo più efficiente sarà un array o 12000 puntatori da strutturare come
char[x] prefix;
DWORD* suffixes;
int n_count;
quindi prefisso, es. 43333 suffisso es. 19821982 => number is 4333319821982
(n_count - > numero di numeri)
Memorizza i numeri senza separatori per risparmiare spazio, un suffisso dopo l'altro (ad esempio il numero 1 è suffisso + 0, il numero 2 è suffisso + 1) e puoi cercare in modo efficiente, se lo hai ordinato.
In questo modo ci vorrebbe solo 4 (DWORD) * 6 miliardi di suffissi = 24 GB di memoria + dimensione di 12k puntatori + prefissi che è irrilevante
Quindi invece di (almeno!) 6 miliardi di puntatori a 64 bit avresti (al massimo!) 6b di suffissi a 32 bit.
Ma probabilmente i numeri sono continui, quindi puoi provare l'array di (start_suffix, end_suffix) invece di memorizzare tutti i suffissi dovrebbero richiedere molto meno.