Newsgroup: it.comp.lang.c
Titolo: concellazione record

Salve, ho un piccolo problema che non riesco a risolvere.
In un file sequenziale ho memorizzato diversi record e vorrei sapere come
posso cancellarli con ricerca per chiave (la ricerca riesco a farla, non so
come eliminarlo una volta trovato) e se (e come faccio a riorganizzare il
file.
Grazie!
--
Marco Ciacci
ra...@amiata.net

 e se (e come faccio a riorganizzare il file.
  L'unica soluzione, in C, e` riscrivere il file omettendo il record in
questione.
	Alla prossima,
		Marco
PS Interessa biancheria intima femminile? :)

Puoi inserire nel record un flag di cancellazione e lasciare la
"ricompattazione" ad un secondo tempo (implica la riscrittura completa del
file).
E' il metodo che usano i database da decenni, sara' perche' funziona.
Ovviamente devi modificare le procedure di ricerca in modo da saltare quelli
"cancellati".
Alessandro Monti


ICQ #34602650

 file.
O marchi i record come cancellati e li lasci disponibili oppure copi
tutti i record non cancellati su un nuovo file.
EMG

Alessandro Monti ha scritto nel messaggio ...

Scusa, ma sono un principiante :)
Cos'è e come si usa un flag di cancellazione?
Grazie!
--
Marco Ciacci

...

Come si realizza cio?
grazie per la pazienza di tutti voi :)
p.s.
Ma i record "marcati" come cancellati posso venir ripristinati, giusto?
--
Marco Ciacci

 Cos'č e come si usa un flag di cancellazione?
In pratica nel tuo record aggiungi un campo (basterebbe un bit, ma magari un
char č meglio) il cui significato banalmente č:
se vale 0 allora NON č cancellato
altrimenti č cancellato
in C qualcosa del tipo:
struct record{
    int campo1;
    char campo2[16];
    ...
    char cancellato;
}
le tue procedure saranno del tipo:
int ricerca (int ricerca_su_campo1){
    ...
    for (fopen(...), fread(...);){
        if (!record_letto.cancellato){
             if (record_letto.campo1 == ricerca_su_campo1)
                ... // Decidi cosa fare quando trovi il record
        }
    }
}
void cancella(struct record *record_da cancellare){
    record_da_cancellare->cancellato++;
}
in piů puoi usare la funzione:
void recupera (struct record *record_da_ripristinare){
    record_da_ripristinare->cancellato = 0;
}
A questo punto, perň, su file avrai una occupazione di memoria maggiore, in
quanto avrai sia i record "buoni" che quelli cancellati.
Perciň ogni tanto (decidi tu quando, magari quando ne hai piů di 100
cancellati) dovrai compattare l'archivio.
La funzione č cosě (in pseudo-codice)
void compatta(){
    rinomina archivio
    apre archivio rinominato
    crea nuovo archivio
    do{
        legge record da archivio rinominato
        se non cancellato copialo su archivio nuovo
    }while (!fine dell'archivio)
    cancella archivio vecchio
}
Spero che adesso sia piů chiaro. Eventualmente scrivi ancora
Alessandro Monti

Forse e' meglio se prima tu aiuti noi a capire:
Credo che tutti abbiamo immaginato che tu abbia scritto
un programma in C (visto che qui si parla di C) dove
hai definito una
struct tuorecordtipo { tipo campo1; tipo campo2;... } tuorecord;
e che si procura da un input i valori, li assegna ai giusto campi
e con write() su un descrittore di file ottenuto con open() o fopen()
li scrive in modo sequenziale.
Ti e' stato consigliato di aggiungere in campo di servizio che puo'
assumere solo due valori a cui tu assegni significato semantico di
stato del record "cancellato" o "non cancellato", campo del tipo piu'
piccolo possibile.
E' chiaro che il record nel file continua ad esistere, ma logicamente
nel database lo puoi considerare inesistente se riprogetti la funzione
di ricerca che ignori i records che hanno tale valore settato. Il data-
bare diventa quindi una struttura dati di livello piu' alto del file.
Naturalmente con strumenti che operano direttamente su file il record
continua ad essere visibile ed e' anche possibile recuperarlo.
Se questo non ti piace, nell' operazione di settaggio del campo di stato
del record (che chiameremo flag di cancellazione) puoi eseguire lo
"sbiancaggio" del record.
Se non sai cone eseguire tale operazione ti ricordo che in C sono
disponi-
bili funzioni standard per l' accesso random ai files:
ftell() fseek() o lseek().
Ci sono anche modi eleganti di gestire record cancellati: io ho scritto
tempo fa del codice che organizzava un file binario in un albero AVL
bilanciato
e gestivo i record cancellati con una pila (stack) di cancellati.
Le operazioni di inserimento quindi prima di appendere un record riuti-
lizzavano lo spazio lasciato da quelli precedentemente cancellati,
naturalmente
cosi' i record non si trovano in sequenza di inserimento e il file deve
essere per forza percorso con apposite funzioni di ricerca.
Alcuni algoritmi semplicissimi da studiare: stack e code.
piu' complessi: alberi binari.
Non so in quale altro modo aiutarti.
ciao


 grazie per la pazienza di tutti voi :)
Ciascun record avrà un flag che indica se è valido o cancellato.
Chiaramente a quel punto l'accesso random al record n-esimo non è più
immediato: supponiamo infatti di avere tre record
RECORD   POSIZIONE FISICA    FLAG CANCELLATO
  1             1                  N
  *             2                  S
  2             3                  N
Come puoi vedere, il numero di record non corrisponde più alla sua
posizione fisica.
Dovrai quindi mantenere un indice, oppure (a seconda delle necessità)
una struttura linked.


 Ma i record "marcati" come cancellati posso venir ripristinati, giusto?
Si.
EMG

you wrote :
#> Ma i record "marcati" come cancellati posso venir ripristinati, giusto?
#
#Si.
Sempre a meno di non implementare un criterio di ottimizzazione dello
spazio occupato nel data-base, in modo simile a quanto il DOS fa per i
file cancellati, ovvero di aggiungere i nuovi record negli spazi
precedentemente occupati da quelli marcati come cancellati.
In questo modo e' possibile che la compattazione dell'archivio non si
renda necessaria, dato che dopo molti inserimenti che seguono molte
cancellazioni, lo spazio viene comunque occupato.
--------------------------------------------------------
* Andrea Laforgia        (
andrea_...@bigfoot.com
) *
--------------------------------------------------------

 precedentemente occupati da quelli marcati come cancellati.
Veramente io pensavo si riferisse al fatto di rendere di nuovo visibili
i record cancellati magari per errore.
EMG

you wrote :
#Veramente io pensavo si riferisse al fatto di rendere di nuovo visibili
#i record cancellati magari per errore.
E difatti e' un'operazione possibile a meno di non implementare un
sistema di cancellazione simile a quello che il DOS adopera per i
file.
