1997-12-23 11:38:42 +00:00
|
|
|
|
#include <recarray.h>
|
|
|
|
|
#include "svlib09.h"
|
|
|
|
|
|
|
|
|
|
#define RWCACHE_SIZE 100
|
|
|
|
|
|
|
|
|
|
// funzione di default: prende una chiave a caso chiave
|
|
|
|
|
const TString & TRWrecord_cache::getkey2discard()
|
|
|
|
|
{
|
|
|
|
|
THash_object * o=get_some_obj();
|
|
|
|
|
CHECK(o,"E' stata chiamata la funzione getkey2discard con la cache vuota");
|
|
|
|
|
return o->key();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TRWrecord_cache::discard(const TString & vittima)
|
|
|
|
|
{
|
|
|
|
|
if (items())
|
|
|
|
|
{
|
|
|
|
|
if (_flags.is_key(vittima))
|
|
|
|
|
{
|
2002-02-26 16:20:19 +00:00
|
|
|
|
const char fl=((TString &)_flags[vittima])[0];
|
1997-12-23 11:38:42 +00:00
|
|
|
|
// record modificato o nuovo
|
2002-02-26 16:20:19 +00:00
|
|
|
|
int err;
|
1997-12-23 11:38:42 +00:00
|
|
|
|
TRectype & rec=(TRectype & )TRecord_cache::get(vittima);
|
|
|
|
|
file().curr()=rec;
|
|
|
|
|
if (fl == 'D')
|
|
|
|
|
{
|
|
|
|
|
err=file().rewrite();
|
2002-02-26 16:20:19 +00:00
|
|
|
|
if (err!=NOERR)
|
|
|
|
|
err=file().write();
|
1997-12-23 11:38:42 +00:00
|
|
|
|
if (err!=NOERR)
|
|
|
|
|
error_box("Errore nella riscrittura della cache");
|
|
|
|
|
} else {
|
|
|
|
|
err=file().write();
|
|
|
|
|
if (err!=NOERR)
|
|
|
|
|
if (err == _isreinsert)
|
|
|
|
|
file().rewrite();
|
|
|
|
|
else
|
|
|
|
|
error_box("Errore nella scrittura della cache");
|
|
|
|
|
}
|
|
|
|
|
_flags.remove(vittima);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
_cache.remove(vittima);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const TRectype& TRWrecord_cache::get(const char* chiave)
|
|
|
|
|
{
|
|
|
|
|
if (items()>=RWCACHE_SIZE)
|
|
|
|
|
discard(getkey2discard());
|
|
|
|
|
const TRectype & rec=TRecord_cache::get(chiave);
|
|
|
|
|
if (io_result() != NOERR)
|
|
|
|
|
{
|
|
|
|
|
// record non trovato: <20> nuovo
|
2002-02-26 16:20:19 +00:00
|
|
|
|
_flags.add(chiave,TString4("N"));
|
1997-12-23 11:38:42 +00:00
|
|
|
|
}
|
|
|
|
|
return rec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TRWrecord_cache::put(const TRectype &r)
|
|
|
|
|
{
|
|
|
|
|
test_firm();
|
|
|
|
|
|
|
|
|
|
TToken_string cachekey;
|
|
|
|
|
if (!r.empty())
|
|
|
|
|
{
|
|
|
|
|
const RecDes* recd = r.rec_des(); // Descrizione del record della testata
|
|
|
|
|
const KeyDes& kd = recd->Ky[key_number()-1]; // Elenco dei campi della chiave
|
|
|
|
|
for (int i = file().tab() ? 1: 0; i < kd.NkFields; i++) // Riempie la chiave selezionata
|
|
|
|
|
{
|
|
|
|
|
const int nf = kd.FieldSeq[i] % MaxFields;
|
|
|
|
|
const RecFieldDes& rf = recd->Fd[nf];
|
2002-02-26 16:20:19 +00:00
|
|
|
|
const TString & fval = r.get(rf.Name);
|
|
|
|
|
cachekey.add(fval);
|
1997-12-23 11:38:42 +00:00
|
|
|
|
}
|
2002-02-26 16:20:19 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
warning_box("adding an empty record");
|
1997-12-23 11:38:42 +00:00
|
|
|
|
TObject* obj = _cache.objptr(cachekey);
|
|
|
|
|
|
|
|
|
|
if (obj != NULL)
|
|
|
|
|
{
|
|
|
|
|
// esiste in cache ; tenta di settare il flag a "D"irty; se il flag esiste gi<67> <20> a
|
1999-04-06 15:34:39 +00:00
|
|
|
|
TRectype & rec=(TRectype &)(*obj);
|
1997-12-23 11:38:42 +00:00
|
|
|
|
rec=r;
|
2002-02-26 16:20:19 +00:00
|
|
|
|
_flags.add(cachekey , TString4("D"));
|
1997-12-23 11:38:42 +00:00
|
|
|
|
} else {
|
|
|
|
|
// non esiste in cache
|
|
|
|
|
obj = rec2obj(r);
|
|
|
|
|
_cache.add(cachekey, obj);
|
|
|
|
|
// qui assume che non esista nemmeno su file, perci<63> sia "N"uovo; al flush corregger<65> l'errore
|
|
|
|
|
_flags.add(cachekey , new TString("N"));
|
|
|
|
|
}
|
|
|
|
|
if (items()>=RWCACHE_SIZE)
|
|
|
|
|
discard(getkey2discard());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TRWrecord_cache::clear()
|
|
|
|
|
{
|
|
|
|
|
while (items()>0)
|
|
|
|
|
{
|
|
|
|
|
const TString & vittima=getkey2discard();
|
|
|
|
|
if (_flags.is_key(vittima))
|
|
|
|
|
_flags.remove(vittima);
|
|
|
|
|
_cache.remove(vittima);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TRWrecord_cache::flush()
|
|
|
|
|
{
|
|
|
|
|
while (items()>0)
|
|
|
|
|
discard(TRWrecord_cache::getkey2discard());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
THash_object * TRWrecord_cache::get_some_obj()
|
|
|
|
|
{
|
|
|
|
|
if (items()==0)
|
|
|
|
|
return NULL;
|
|
|
|
|
THash_object * o;
|
|
|
|
|
while ((o=_cache.get_hashobj()) == NULL) ;
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TRWrecord_cache::TRWrecord_cache(TLocalisamfile *f, int key, bool lock)
|
|
|
|
|
:TRecord_cache(f,key)
|
|
|
|
|
{
|
|
|
|
|
if (lock)
|
|
|
|
|
file().lock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TRWrecord_cache::TRWrecord_cache(int num, int key, bool lock)
|
|
|
|
|
:TRecord_cache(num,key)
|
|
|
|
|
{
|
|
|
|
|
if (lock)
|
|
|
|
|
file().lock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TRWrecord_cache::~TRWrecord_cache()
|
|
|
|
|
{
|
|
|
|
|
flush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|