00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #ifndef FILE_CACHE_MANAGER_H
00022 #define FILE_CACHE_MANAGER_H
00023 
00024 #include<cstdio>
00025 #include<map>
00026 using namespace std;
00027 
00034 template <typename Key, typename Data>
00035 class cache_manager {
00036 
00037  public:
00040   typedef Key key_type;
00041 
00044   typedef Data data_type;
00045 
00046   typedef std::map<Key, std::pair<bool,data_type*> > storage_type;
00047 
00050   typedef unsigned long long size_type;
00051 
00054   typedef std::map< key_type, std::pair<unsigned long long,unsigned long long> , std::less< key_type > > FileMap;
00055     
00056   typedef typename FileMap::iterator File_Map_iter;
00062   typedef typename storage_type::iterator storage_iterator;    
00063     
00066   typedef typename storage_type::const_iterator storage_const_iterator;
00067     
00070   typedef typename storage_type::value_type storage_entry_type;
00071 
00072   
00075   storage_iterator begin() { return istorage_.begin(); }
00076 
00079   storage_iterator end() { return istorage_.end(); }
00080 
00083   storage_const_iterator begin() const { return istorage_.begin(); }
00084 
00087   storage_const_iterator end() const { return istorage_.end(); }
00088 
00096   
00097   explicit cache_manager(size_type C = 0,const char* filename)
00098     : size_(0), capacity_(C), istorage_(), offset(0), file_name(filename){
00099     my_file_.open(file_name.c_str(), 
00100                   std::ios::in|std::ios::out|std::ios::binary|ios::trunc);   
00101 
00102   } 
00103     
00104     
00105   ~cache_manager() {
00106     my_file_.close();
00107     
00108     if (remove(file_name.c_str()) < 0){
00109       cerr << "Unable to remove backend file " << file_name << endl;
00110     }
00111   }
00112   
00115   void clear() {
00116     
00117     size_ = 0;
00118     istorage_.clear();
00119     file_map_.clear();
00120   } 
00121 
00124   size_type size() const { 
00125     size_type S = size_;
00126     return S; 
00127   } 
00128 
00129     
00132   size_type capacity() const {
00133     size_type S = capacity_;
00134     return S;
00135   } 
00136 
00139   size_type mem_entries() const {
00140     size_type S = istorage_.size();
00141     return S;
00142   } 
00143 
00146   void print_stats() const {
00147     
00148   } 
00151   size_type file_entries() const {
00152     size_type S = file_map_.size();
00153     return S;
00154   } 
00155 
00156 
00157     
00160   storage_const_iterator find(const key_type& k) const {
00161     storage_const_iterator iter(istorage_.find(k));
00162     return iter;
00163   } 
00164   
00165   void lock_vat(const key_type& k) {
00166     storage_iterator iter(istorage_.find(k));
00167     if (iter != istorage_.end()) {
00168         iter->second.first=1;
00169     } 
00170   } 
00171 
00172   void unlock_vat(const key_type& k) {
00173     storage_iterator iter(istorage_.find(k));
00174     if (iter != istorage_.end()) {
00175       iter->second.first=0;
00176     } 
00177   } 
00178 
00182   void  delete_vat(const key_type& k){
00183     storage_iterator iter(istorage_.find(k));
00184     if (iter != istorage_.end()){ 
00185       size_ -= iter->second.second->byte_size();
00186       data_type* v =iter->second.second;
00187       if(v){
00188         delete v; 
00189       }
00190       else 
00191         std::cout<<"cache_manager.delete_vat: vat is null"<<endl;
00192       
00193       istorage_.erase(iter); 
00194     } 
00195     file_map_iter = file_map_.find(k);
00196     if(file_map_iter != file_map_.end()){   
00197       file_map_.erase(file_map_iter);
00198     }
00199 
00200   }
00201 
00206   bool find_vat ( const key_type& k ){
00207     storage_iterator iter(istorage_.find(k));  
00208     if (iter != istorage_.end()){ 
00209       return true;
00210     }
00211     file_map_iter = file_map_.find(k);  
00212     if(file_map_iter != file_map_.end()){   
00213       return true;
00214     }
00215     return false; 
00216   } 
00217   
00221   data_type * get_vat_point(const key_type& k) {
00222     storage_iterator iter(istorage_.find(k));
00223     if (iter != istorage_.end()) {
00224       return iter->second.second;
00225     } 
00226     else { 
00227       file_map_iter = file_map_.find(k);
00228       if(file_map_iter != file_map_.end()){
00229         my_file_.seekg(file_map_iter->second.second);
00230         data_type* temp_object=new data_type();
00231         temp_object->read_file(my_file_,file_map_iter->second.first); 
00232         insert(k,temp_object);
00233         
00234         return get_vat_point(k);          
00235       } 
00236       else{
00237         cout <<"Inside file_cache_manager::get_vat_point. Vat is neither in mem nor in file!!"<<endl;
00238       }
00239     } 
00240 
00241     return 0;
00242   }
00243 
00251   bool insert(const key_type& k, data_type* e) {
00252     if (capacity_ < size_ + e->byte_size()) {
00253       if (update(e->byte_size(),0) == false) {
00254         cout<<"insert: update problem\n" << ".bytesize: " << e->byte_size()<<endl;
00255         return false;
00256       }
00257     }
00258     istorage_.insert(entry_type(k,std::pair<bool,data_type*>(0,e)));
00259     size_ += e->byte_size();
00260     return true;
00261   } 
00262 
00263   
00264 
00265 
00266   bool update(size_type req_size = 0,int levelone=1) {
00267     if (istorage_.empty()) {    
00268       cout<<"Nothing in the memory..Update Failed"<<endl;
00269       return false;
00270     }
00271 
00272     long int S = 0;
00273     if (req_size > 0) S = capacity_ - size_ - req_size;
00274 
00275     storage_iterator iter;
00276     do {
00277     iter = istorage_.begin();    
00278     
00279     while (iter->second.first ==1 && iter != istorage_.end())  {
00280       iter++;
00281     }
00282 
00283     if (iter == istorage_.end()){
00284       cout <<"Nothing can be evicted from memory"<<endl;
00285       return false;
00286     }
00287     
00288     S += iter->second.second->byte_size();
00289     size_ =  size_ - iter->second.second->byte_size();
00290     
00291     
00292     file_map_iter = file_map_.find( iter->first); 
00293     
00294     if( file_map_iter == file_map_.end() || levelone ){
00295       my_file_.seekp(offset);
00296       std::pair<size_type, size_type> file_offset_info(iter->second.second->byte_size(),offset);
00297       file_map_[iter->first]=file_offset_info; 
00298       offset += iter->second.second->byte_size();
00299       iter->second.second->write_file(my_file_);
00300     }
00301      
00302     if(iter->second.second)
00303        delete iter->second.second; 
00304      else 
00305        std::cout<<"cache_manager.update: vat is null"<<endl;
00306       
00307     istorage_.erase(iter);
00308     
00309     if ((istorage_.empty()) && (S < 0)) {
00310       cout<<"Nothing in the memory..Update Failed"<<endl;
00311       return false;
00312     }
00313   }
00314   while (S <= 0);
00315   return true;
00316     
00317 } 
00318 
00319 private:
00320 
00321 
00322 cache_manager(const cache_manager&);
00323 cache_manager& operator=(const cache_manager&);
00324 typedef std::pair<storage_iterator, bool> result_type;
00325 typedef std::pair<size_type, size_type> pair_type;           
00326 typedef std::pair<key_type, std::pair<bool,data_type*> > entry_type;
00327 
00328 File_Map_iter file_map_iter;  
00329 
00330 size_type size_; 
00331 size_type capacity_; 
00332 storage_type istorage_; 
00333 FileMap  file_map_; 
00334 size_type offset;  
00335 std::fstream my_file_; 
00336  string file_name; 
00337 
00338 }; 
00339 
00340 #endif // FILE_CACHE_MANAGER_H