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:
parent
c497f91f9f
commit
f1c8e53279
@ -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
|
||||
|
152
ab/ablib01.cpp
152
ab/ablib01.cpp
@ -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
|
||||
|
11
ab/ablib01.h
11
ab/ablib01.h
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user