Files correlati : sv?.exe Ricompilazione Demo : [ ] Commento : Aggiornato uso FileDes git-svn-id: svn://10.65.10.50/trunk@17860 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <recarray.h>
 | 
						|
#include <diction.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])[0];
 | 
						|
      // 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)
 | 
						|
          err=file().write();
 | 
						|
        if (err!=NOERR)
 | 
						|
          error_box(TR("Errore nella riscrittura della cache"));
 | 
						|
      } else {
 | 
						|
        err=file().write();
 | 
						|
        if (err!=NOERR)
 | 
						|
          if (err == _isreinsert)
 | 
						|
            file().rewrite();
 | 
						|
          else
 | 
						|
            error_box(TR("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,TString4("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];  
 | 
						|
      const TString & fval = r.get(rf.Name);
 | 
						|
      cachekey.add(fval);
 | 
						|
    }
 | 
						|
  }           
 | 
						|
  else
 | 
						|
    warning_box(TR("adding an empty record"));
 | 
						|
  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 , TString4("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();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 |