diff --git a/sv/svlib09.cpp b/sv/svlib09.cpp new file mode 100755 index 000000000..19145decd --- /dev/null +++ b/sv/svlib09.cpp @@ -0,0 +1,147 @@ +//#include +//#include +#include + +//#include "svlib01.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)) + { + const char fl=((TString &)_flags[vittima])[1]; + // record modificato o nuovo + int err; + TRectype & rec=(TRectype & )TRecord_cache::get(vittima); + file().curr()=rec; + if (fl == 'D') + { + err=file().rewrite(); + 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: è nuovo + _flags.add(chiave,new TString("N")); + } + 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]; + cachekey.add(r.get(rf.Name)); + } + } + TObject* obj = _cache.objptr(cachekey); + + if (obj != NULL) + { + // esiste in cache ; tenta di settare il flag a "D"irty; se il flag esiste già è a + TRectype & rec=(TRectype &)*obj; + rec=r; + _flags.add(cachekey , new TString("D")); + } else { + // non esiste in cache + obj = rec2obj(r); + _cache.add(cachekey, obj); + // qui assume che non esista nemmeno su file, perciò sia "N"uovo; al flush correggerà 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(); +} + + + diff --git a/sv/svlib09.h b/sv/svlib09.h new file mode 100755 index 000000000..01fe5b352 --- /dev/null +++ b/sv/svlib09.h @@ -0,0 +1,41 @@ +#ifndef __SVLIB09_H +#define __SVLIB09_H + +#ifndef __ASSOC_H +#include "assoc.h" +#endif + +#ifndef __VELIB_H +#include "..\ve\velib.h" +#endif + +#ifndef __TABUTIL_H +#include +#endif + +#include "..\mg\mglib.h" + +class TRWrecord_cache : public TRecord_cache +{ + TAssoc_array _flags; + +protected: + THash_object * get_some_obj(); + virtual const TString & getkey2discard(); +public: + virtual void discard(const TString & k); + virtual void put(const TRectype &r); + virtual const TRectype& get(const char* chiave); + + void clear(); + void flush(); + + TRWrecord_cache(TLocalisamfile *f, int key = 1, bool lock=FALSE); + TRWrecord_cache(int num, int key = 1, bool lock=FALSE); + TRWrecord_cache(const char* table, int key = 1, bool lock=FALSE); + virtual ~TRWrecord_cache() ; + const TAssoc_array * internal_array() {return &_cache;} +}; + +#endif +