Modificata la gestione degli "status" dei nodi: prima metteva sempre nodo modificato

anche quando in realtà non modificava nulla.
Modificata di conseguenza anche la funzione per la rimozione dei nodi che si basava
sugli "status".


git-svn-id: svn://10.65.10.50/trunk@5979 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
sauro 1998-01-20 10:14:04 +00:00
parent c497f91f9f
commit f1c8e53279
3 changed files with 58 additions and 109 deletions

View File

@ -12,8 +12,8 @@ void test_analisi()
anas.put(ABAN_CODAN,"A1");
anas.read();
// readat -> vedi dopo
anas.remove(); //Solo per il test della delete_node o la rimozione di una intera tabella
//anas.write();
//anas.remove(); //Solo per il test della delete_node o la rimozione di una intera tabella
anas.write();
/*Questa parte della funzione serve solo per testare la readat

View File

@ -1,10 +1,4 @@
#include "ablib01.h"
#define MAX_ID_REL 999999999
#define NODO_AGGIUNTO "A"
#define NODO_MODIFICATO "M"
#define NODO_RIMOSSO "R"
/**************************************************************************************************/
// TAlbero_AB
/**************************************************************************************************/
@ -63,11 +57,11 @@ int TAlbero_AB::readat(TBaseisamfile& analisi, TRecnotype nrec, word lockop)
int TAlbero_AB::remove(TBaseisamfile& f) const
{
//*Abilitare questa parte solo per effettuare un debug della delete_node
/*Abilitare questa parte solo per effettuare un debug della delete_node
// anche se messa in questa posizione, la chiamata non ha senso
// TLocalisamfile lf(LF_RELANA);
TNumeric_id id;
id = 17;
id = 4;
_inter_tree->delete_node(id);
int errc = commit_body();
if (errc != NOERR)
@ -76,10 +70,10 @@ int TAlbero_AB::remove(TBaseisamfile& f) const
//return errc;
}
return 0;
*/
/*Abilitare solo questa parte per il test della remove_tree
//*Abilitare solo questa parte per il test della remove_tree
_inter_tree->delete_tree();
int errc = commit_body();
if (errc != NOERR)
@ -88,7 +82,7 @@ int TAlbero_AB::remove(TBaseisamfile& f) const
//return errc;
}
int err = TRectype::remove(f);
return err; */
return err;
}
void TAlbero_AB::zero()
@ -129,65 +123,9 @@ void TABsaldo::put_headkey(TRectype &rec) const
rec.put(ABMD_CODCBL, get(ABS_CODCBL));
}
/*
int TABsaldo::commit_body() const
{
_inter_tree->write_cache();
TRectype rec(_inter_tree->current().num());
TLocalisamfile filebody(rec.num());
TString status;
//Estraggo un nodo per volta basandomi sull'assoc_array degli status
while (_inter_tree->dirty_nodes() > 0)
{
TNumeric_id id;
//int prova = _inter_tree->dirty_nodes(); //solo debug
id=ID_NULLO;
rec= _inter_tree->extract_dirtynode(id, status);
put_headkey(rec);
//Ho un rectype e uno status node
if (status == NODO_AGGIUNTO)
{
if (filebody.curr().empty())
{ //Se il cursor di relana è posizionato in modo errato:
//lo sistemo sull'ultimo record del file
//DOMANDA: - Perchè ???
//TENATATIVO DI RISPOSTA: - Quando l'ultima azione effettuata (prima di questa "aggiunta") è la rimozione
// dell'ultimo record probabilmente (ma non sono sicuro) il cursore non è posizionato (o forse
// è posizionato in modo errato come ad es. dopo l'EOF, visto che l'EOF era sull'ultimo record rimosso)
// e quando eseguo un tentativo di scrittura da un errore di chiave duplicata (anche se questa non esiste);
// In tutti gli altri casi (quando l'ultima azione è stata una write o una rewrite o una remove di un record
// che non sia l'ultimo) questo problema non esiste.
//RISPOSTA ESATTA: - Bho !!!
filebody.last();
}
int err = filebody.write(rec);
if (err != NOERR)
return err;
}
if (status == NODO_MODIFICATO)
{
int err = filebody.rewrite(rec);
if (err != NOERR)
return err;
}
if (status == NODO_RIMOSSO)
{
filebody.read(rec); //Devo leggere sul file per posizionare il cursore: stesso motivo di prima
int err = filebody.remove(rec);
if (err != NOERR)
return err;
}
// In tutti gli altri casi il nodo non viene modificato
}
return NOERR;
}
*/
//Leggo il "corpo" del record
int TABsaldo::read_body(bool lockstruct)
{
//_ana = new TAlbero_relana(get(ABAN_CODAN));
TString codditta = get(ABS_CODDITTA);
TToken_string key = codditta.right_just(5,'0');
key.add(get(ABS_ANNO));
@ -198,11 +136,9 @@ int TABsaldo::read_body(bool lockstruct)
if (_mov->goto_root())
{
//TNumeric_id id_movdett;
//id_movdett = _mov->curr().get_real(ABMD_ID);
naviga_movdett();
}
//_inter_tree->write_cache(); //solo per debug
// _inter_tree->write_cache(); //solo per debug
return 0;
}
@ -217,7 +153,7 @@ void TABsaldo::naviga_movdett()
pather_id = _mov->curr().get_real(ABMD_IDPADRE);
lbrother_id = _mov->curr().get_real(ABMD_IDPREC);
*_newrec = _mov->curr();
_inter_tree->insert_node(*_newrec,lbrother_id,pather_id,my_id);
_inter_tree->insert_node(*_newrec,lbrother_id,pather_id,my_id,TRASFERITO);
if (_mov->has_rbrother())
{
@ -282,7 +218,7 @@ int TAlbero_AB::commit_body() const
while (_inter_tree->dirty_nodes() > 0)
{
TNumeric_id id;
// int prova = _inter_tree->dirty_nodes(); solo debug
// int prova = _inter_tree->dirty_nodes(); //solo debug
id=ID_NULLO;
rec= _inter_tree->extract_dirtynode(id, status);
@ -366,7 +302,7 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
_relaz->curr_id(key_rel);
_newrec = sincronizza_relana(begin_relana, id_relana);
currid=_newrec->get_real(ABRA_ID);
_inter_tree->insert_node(*_newrec,id_prec,id_padre,currid);
_inter_tree->insert_node(*_newrec,id_prec,id_padre,currid,TRASFERITO);
//Controllo se c'è un fratello di rel_voci
if (_relaz->has_rbrother())
@ -377,7 +313,6 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
//fra relvoci e relana
TNumeric_id frat_relana;
naviga_relazioni(frat_relana,currid , id_padre);
//_ana->goto_node(key_ana); //Per risalire al nodo che mi ha chiamato in relana
_relaz->goto_node(key_rel);
}
else
@ -396,7 +331,6 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
id_relana=_ana->curr().get_real(ABRA_ID);
}
naviga_relazioni(id_relana, ID_NULLO , currid);
//_ana->goto_node(key_ana); //Per risalire al nodo che mi ha chiamato in relana
}//Se non trovo il figlio di una relazione, potrebbe essere una foglia di un ramo dell'albero
_relaz->goto_node(key_rel); //Per risalire al nodo che mi ha chiamato in relvoci
}
@ -649,9 +583,9 @@ TNumeric_id &TAlbero_locale::new_id(TNumeric_id id)
//Inserisce il nodo (che ho in ingresso) nella struttura ad albero doppiamente linkata
//di relana aggiornando tutti i link
bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id)
bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char flag_it)
{
const int dirty_value=NODO_MODIFICATO;
const char* dirty_value=NODO_MODIFICATO;
TNumeric_id id_succ;
TToken_string key;
key=get_headkey();
@ -665,9 +599,12 @@ bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, cons
{ //Aggiorno il successivo del mio precedente dicendogli che il suo successivo sono io
key.add(id_prec.string());
parente = _local_cache->get(key);
parente.put(idsucc_fieldname(),id.string());
_local_cache->put(parente);
set_status_node(id_prec,dirty_value); //Setto l'eventuale flag di array modificato per il fratello
if (parente.get_real(idsucc_fieldname()) != id)
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
parente.put(idsucc_fieldname(),id.string());
_local_cache->put(parente);
set_status_node(id_prec,dirty_value); //Setto l'eventuale flag di array modificato per il fratello
}
}
else
{ //Se non ho il mio precedente, allora o sono una radice principale o divento il primo figlio:
@ -675,23 +612,33 @@ bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, cons
{ //Sono un primo figlio: rintraccio mio padre e gli dico che il suo primo figlio ora, sono io
key.add(id_padre.string());
parente = _local_cache->get(key);
parente.put(idson_fieldname(),id.string());
_local_cache->put(parente);
set_status_node(id_padre,dirty_value); //Setto l'eventuale flag di array modificato per il padre
if(parente.get_real(idson_fieldname()) != id)
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
parente.put(idson_fieldname(),id.string());
_local_cache->put(parente);
set_status_node(id_padre,dirty_value); //Setto l'eventuale flag di array modificato per il padre
}
} // Sono una radice principale e quindi sono orfana di padre
}
//Ora aggiorno me stesso
put_headkey(node);
// node.put(ABRA_CODAN,get_headkey()); //Eseguo un combio della chiave: non serve avere il codice della tabella nella cache
node.put(idprec_fieldname(),id_prec.string());
node.put(idfather_fieldname(),id_padre.string());
node.put(idsucc_fieldname(),id_succ.string());
node.put(idson_fieldname(),ID_NULLO);
if ((node.get_real(idprec_fieldname()) != id_prec) ||
(node.get_real(idfather_fieldname()) != id_padre))
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
node.put(idprec_fieldname(),id_prec.string());
node.put(idfather_fieldname(),id_padre.string());
set_status_node(id,dirty_value);
}
if (flag_it == IMMESSO)
{
node.put(idsucc_fieldname(),id_succ.string());
node.put(idson_fieldname(),ID_NULLO);
//set_current(node);
}
_local_cache->put(node);
//set_current(node);
goto_node(node);
set_status_node(id,dirty_value);
return TRUE;
}
@ -721,7 +668,8 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
parente=_local_cache->get(key); //padre
if (parente.get(idson_fieldname()) == id.string())
{ //Il nodo che sta per essere rimosso è il primo figlio di un padre
parente.put(idson_fieldname(),id_succ.string()); //Aggiorno il padre
parente.put(idson_fieldname(),id_succ.string()); //Aggiorno il padre
set_status_node(id_padre, NODO_MODIFICATO); //Aggiorno lo status
_local_cache->put(parente);
}
}
@ -735,6 +683,7 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
key.add(id_prec.string());
parente=_local_cache->get(key); //fratello sinistro
parente.put(idsucc_fieldname(),id_succ.string()); //Assegno al mio fratello sinistro il mio fratello destro
set_status_node(id_prec,NODO_MODIFICATO); //Aggiorno lo status
_local_cache->put(parente);
}
@ -747,6 +696,7 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
key.add(id_succ.string());
parente=_local_cache->get(key); //fratello destro
parente.put(idprec_fieldname(),id_prec.string()); //Assegno al mio fratello destro il mio fratello sinistro
set_status_node(id_succ,NODO_MODIFICATO); //Aggiorno lo status
_local_cache->put(parente);
}
@ -831,23 +781,15 @@ bool TAlbero_locale::remove_subtree(const TNumeric_id return_id)
//in modo tale da mantenerlo allineato con il contenuto della cache
TString *status;
status = (TString*)_status_node.objptr(id.string());
if (status != ID_NULLO)
{//Se esiste uno stato per questo nodo
if ((*status == NODO_MODIFICATO) || (*status == NODO_RIMOSSO))
{//In questi due casi il nodo esisteva già nel file originario
_status_node.add(id.string(),(TString)NODO_RIMOSSO,TRUE); //Forzo la sovrascrittura in ogni caso
}
else
{//Nel caso di NODO_AGGIUNTO
_status_node.remove(id.string());
}
if ((status == NULL) || (*status != NODO_AGGIUNTO))
{//In questi due casi il nodo esisteva già nel file originario
_status_node.add(id.string(),(TString)NODO_RIMOSSO,TRUE); //Forzo la sovrascrittura in ogni caso
}
else
{
//Questo caso non dovrebbe verificarsi poichè un nodo per cui
//non è previsto uno status, non dovrebbe esistere nella cache
CHECK (FALSE,"Errore nella consistenza della cache");
{//Nel caso di NODO_AGGIUNTO
_status_node.remove(id.string());
}
if (return_id != ID_NULLO)
goto_node(return_id);
else

View File

@ -31,6 +31,13 @@
#include "saldi.h"
#include "movdett.h"
#define MAX_ID_REL 999999999
#define NODO_AGGIUNTO "A"
#define NODO_MODIFICATO "M"
#define NODO_RIMOSSO "R"
#define IMMESSO 'I'
#define TRASFERITO 'T'
@ -294,8 +301,8 @@ class TAlbero_locale : public TAlbero_bidir
// debug
void write_cache() { _local_cache->flush(); }
// @cmember Inserisce un nodo in una struttura di tipo lista doppiamente lincata
bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id);
// @cmember Inserisce un nodo in una struttura di tipo lista doppiamente lincata: trasf_immes è un flag che dice se il nodo è trasferito o immesso
bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char trasf_immes);
// @cmember Elimina un nodo da una struttura di tipo lista doppiamente lincata
bool delete_node(const TNumeric_id &id);
// @cmember Lancia la rimozione di tutto l'albero