Jerry ha ragione, se è solo Ctrl-C sei preoccupato, puoi ignorare SIGINT per i periodi alla volta. Se vuoi essere una prova contro la morte del processo in generale, hai bisogno di una sorta di journalling minimale. Per scambiare due elementi:
1) Aggiungere un record a una struttura di controllo alla fine del file o in un file separato, indicando quali due elementi del file si intende scambiare, A e B.
2) Copia A nello spazio di lavoro, registra che lo hai fatto, a filo.
3) Copia B su A, quindi registrare nello spazio graffio che avete fatto così, a filo
4) Copia dallo spazio zero nel corso B.
5) Rimuovere il record.
Questo è O (1) spazio aggiuntivo per tutti gli scopi pratici, quindi conta ancora come posto nella maggior parte delle definizioni. In teoria, la registrazione di un indice è O (log n) se n può essere arbitrariamente grande: in realtà è un log n molto piccolo, e ragionevole hardware/tempo di esecuzione lo limita sopra a 64.
In tutti i casi quando dico " flush ", intendo che commetto i cambiamenti" abbastanza lontano ". A volte l'operazione di flush di base esegue solo lo svuotamento dei buffer all'interno del processo, ma in realtà non sincronizza il supporto fisico, perché non svuota i buffer completamente attraverso i livelli del driver/hardware del sistema operativo. Questo è sufficiente quando tutto ciò di cui sei preoccupato è la morte del processo, ma se sei preoccupato per l'improvviso smarrimento dei media, dovrai lavare il driver. Se fossi preoccupato per l'interruzione di corrente, dovresti sincronizzare l'hardware, ma non lo sei. Con un UPS o se pensi che le interruzioni di corrente siano così rari non ti dispiace perdere i dati, va bene.
All'avvio, controllare lo spazio zero per eventuali record "swap in progress".Se ne trovi uno, calcola quanto lontano hai e completa lo scambio da lì per riportare i dati in uno stato sonoro. Quindi inizia di nuovo il tuo tipo.
Ovviamente c'è un problema di prestazioni qui, dal momento che stai facendo il doppio dei record di scrittura di prima, e gli svuotamenti/sincronizzazioni possono essere sorprendentemente costosi. In pratica, il tuo ordinamento sul posto potrebbe avere delle operazioni di roba composta, che implicano molti scambi, ma che puoi ottimizzare per evitare che ogni elemento colpisca lo spazio di lavoro. Devi solo assicurarti che prima di sovrascrivere qualsiasi dato, ne hai una copia da qualche parte e un record di dove dovrebbe essere quella copia per riportare il tuo file a uno stato in cui contiene esattamente una copia di ciascun elemento.
Jerry ha anche ragione che il vero ordinamento sul posto è troppo difficile e lento per la maggior parte degli scopi pratici. Se è possibile risparmiare parte lineare della dimensione del file originale come spazio zero, si avrà un tempo molto migliore con un ordinamento di fusione.
Sulla base dei vostri chiarimenti, non avreste bisogno di alcuna operazione di scarico anche con un ordinamento sul posto. Hai bisogno di spazio di memoria in memoria che funzioni allo stesso modo e che il tuo gestore SIGINT possa accedere per rendere i dati protetti prima dello in uscita, piuttosto che ripristinare all'avvio dopo un'uscita anomala ed è necessario accedere a quella memoria in un modo sicuro dal punto di vista dei segnali (che tecnicamente significa usare uno sig_atomic_t
per segnalare quali modifiche sono state apportate). Anche così, probabilmente stai meglio con un mergesort di un vero ordinamento sul posto.
Penso che devi chiedere Qual è più importante? Spazio o se il processo deve essere interrotto.Se hai bisogno di assicurarti che il file non sia corrotto, dovrai tenere traccia dei suoi progressi e degli stati precedenti in qualche modo - questo occuperà più spazio del file. –
Per sicurezza. Fai una copia e ordina la copia. Non riesco a immaginare che il file system avrebbe problemi con un altro 40GB –
@ Martin: la tua immaginazione non funziona come fa il mio. Sulla mia unità primaria attualmente ho 36,4 GB gratuiti. –