Scorporata la classe TRWcache dalla libreria normale delle statistiche
I files svlib09.cpp e svlib09.h permettono la gestione delle cache di lettura e SCRITTURA che operano su un Localisamfile Il metodo più importante è "put(rectype)", simmetrico di get() delle cache normali. La cache ha un algoritmo di discarding semplice (sbatte via una chiave a caso) ma è possibile imporre una politica particolare mediante la ridefinizione della funzione virtuale getkey2discard() git-svn-id: svn://10.65.10.50/trunk@5782 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
f87f98ad6b
commit
3445312adb
147
sv/svlib09.cpp
Executable file
147
sv/svlib09.cpp
Executable file
@ -0,0 +1,147 @@
|
||||
//#include <prefix.h>
|
||||
//#include <progind.h>
|
||||
#include <recarray.h>
|
||||
|
||||
//#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();
|
||||
}
|
||||
|
||||
|
||||
|
41
sv/svlib09.h
Executable file
41
sv/svlib09.h
Executable file
@ -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 <tabutil.h>
|
||||
#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
|
||||
|
Loading…
x
Reference in New Issue
Block a user