1 #include "configcache.h"
8 configcache::configcache(const string& cacheid, const int& nequi, const int& nskip, const string& datadir, char **configmem, const int& configMemSize, const int& cachemode,
17 configMem = (char*)malloc(configMemSize);
18 tmpConfig = (char*)malloc(configMemSize);
20 *configmem = configMem;
21 configSize = configMemSize;
28 refetchDataFiles = false;
31 string configcache::getFileId(const bool& shortid)
35 if(!shortid) fileid << CACHEID << "_" << NEQUI << "_" << NSKIP;
36 for(int ipara=0; ipara<Paras.size(); ipara++)
37 fileid << "_" << Paras[ipara].id << Paras[ipara].val;
42 void configcache::fetchDataFiles()
44 struct dirent *de=NULL;
46 static infiledesc filedesc;
48 d=opendir(DATADIR.c_str());
50 while(de = readdir(d)){
51 string filename = de->d_name;
52 if(isValidInFile(filename, &filedesc))
54 inFiles.push_back(filedesc);
60 bool configcache::isValidInFile(const string& infile, infiledesc *filedesc)
62 char *inchar, *inParts;
63 string truncIn, truncOut;
65 filedesc->filename = infile;
66 filedesc->doVirtualEquilibration = false;
68 if( infile.size() < 4 ) return false;
70 if( infile.substr(infile.size()-4) == ".dat" )
71 filedesc->extended = false;
72 else if( infile.substr(infile.size()-4) == "edat" )
73 filedesc->extended = true;
77 inchar = new char [infile.size()+1];
78 strcpy (inchar, infile.c_str());
80 inParts = strtok( inchar, "_" );
81 for(int iPart=0; inParts!=NULL; iPart++)
83 if( iPart>3 ) { truncIn += "_"; truncIn += inParts; }
87 case 1: if(inParts != CACHEID) return false; break;
89 if (atoi(inParts) > NEQUI)
91 else if (atoi(inParts) < NEQUI)
92 filedesc->doVirtualEquilibration = true;
93 filedesc->nequi = atoi(inParts);
96 if(atoi(inParts) != NSKIP)
98 filedesc->nskip = atoi(inParts);
101 inParts = strtok( NULL, "_");
103 truncIn = truncIn.substr(0, truncIn.size()-4);
107 if( truncIn.find( getFileId(true) + "_" ) == string::npos ) return false;
112 bool configcache::openInFile() {
113 while( (!inFile.is_open()) && inFiles.size() > 0 )
115 if(out) *out->log << "CCACHE: Opening dat-file: " << inFiles.back().filename << endl << flush;
117 openFileDesc = inFiles.back();
118 inFile.open( (DATADIR + "/" + inFiles.back().filename).c_str(), std::ios::binary );
121 if( !inFile.is_open() ) continue;
123 inBuffer = new boost::iostreams::filtering_istreambuf;
124 inBuffer->push( boost::iostreams::bzip2_decompressor() );
125 inBuffer->push(inFile);
133 void configcache::readHeader()
137 if( readDataToMem((char*)&headersize, sizeof(int)) == sizeof(int) && inFile.is_open() )
139 if( headerData != NULL ) delete headerData;
141 headerData = new char(headersize);
143 if( readDataToMem(headerData, headersize) == headersize && inFile.is_open() ) {
144 if(out) *out->log << "CCACHE: Read header information." << endl << flush;
147 if(out) *out->log << "CCACHE: Could not read header! Closing dat-file: " << openFileDesc.filename << endl << flush;
152 if(out) *out->log << "CCACHE: Could not read header size! Closing dat-file: " << openFileDesc.filename << endl << flush;
157 void *configcache::getHeader() {
161 bool configcache::readConfig()
163 if(DATADIR == "" || MODE == CACHE_MODE_DISABLED) return false;
165 if(refetchDataFiles){
166 refetchDataFiles = false;
172 if( (!inFile.is_open()) && inFiles.size() == 0 ) return false;
174 /* read header information */
175 if ( openInFile() && openFileDesc.extended )
178 if( inFile.is_open() )
180 if (openFileDesc.doVirtualEquilibration) {
181 if(out) *out->log << "CCACHE: Trying virtual equilibration." << endl << flush;
182 openFileDesc.doVirtualEquilibration = false;
183 for (int iskip=0; iskip < (NEQUI-openFileDesc.nequi)/openFileDesc.nskip; iskip++) {
184 if( readDataToMem(tmpConfig, configSize) != configSize || ! inFile.is_open() )
189 if( readDataToMem(tmpConfig, configSize) == configSize && inFile.is_open() )
191 memcpy(configMem, tmpConfig, configSize);
195 if(out) *out->log << "CCACHE: Could not read configuration. Closing dat-file: " << openFileDesc.filename << endl << flush;
202 void configcache::openOutFile()
204 time_t secstamp = time(NULL);
207 outFileName << DATADIR << "/" << secstamp << "_" << getFileId() << "_.edat.tmp";
208 outFile.open( outFileName.str().c_str(), std::ios::binary );
210 outBuffer = new boost::iostreams::filtering_ostreambuf;
211 outBuffer->push(boost::iostreams::bzip2_compressor());
212 outBuffer->push(outFile);
215 void configcache::writeHeader(char *header, const int& size) {
216 if( DATADIR == "" || MODE < 2 ) return;
218 if(!outFile.is_open()) {
220 boost::iostreams::write(*outBuffer, header, size);
223 if(out) *out->log << "CCACHE: Not writing header because outfile is already open!" << endl << flush;
226 void configcache::writeConfig()
228 if( DATADIR == "" || MODE < 2 ) return;
230 if(!outFile.is_open()){
233 boost::iostreams::write(*outBuffer, (char*)&zeroheader, sizeof(int));
236 boost::iostreams::write(*outBuffer, configMem, configSize);
239 void configcache::addPara(const string& parid, const double& val){
243 Paras.push_back(newPara);
246 int configcache::getParIndex(const string& parid){
247 for(int ipara=0; ipara<Paras.size(); ipara++)
248 if(Paras[ipara].id == parid) return ipara;
251 void configcache::setPara(const string& parid, const double& value){
252 Paras[getParIndex(parid)].val = value;
254 if(inBuffer != NULL) { delete inBuffer; inBuffer=NULL; }
258 refetchDataFiles = true;
261 configcache::~configcache()
268 void configcache::finishOutFile()
270 if( outBuffer != NULL )
276 if( outFile.is_open() )
279 rename( outFileName.str().c_str(), outFileName.str().substr(0, outFileName.str().size()-4).c_str() );
283 int configcache::readDataToMem(char *tmpData, long unsigned int dataSize)
287 if ( dataSize == 0 ) return 0;
289 try { readturn = boost::iostreams::read(*inBuffer, tmpData, dataSize); }
290 catch(boost::iostreams::bzip2_error& error) {
291 if(out) *out->log << "CCACHE: Caught bzip2 exception with error code: " << error.error() << endl << flush;
294 catch (std::exception const& ex) {
295 if(out) *out->log << "CCACHE: Caught exception: " << ex.what() << endl << flush;
299 if(out) *out->log << "CCACHE: Caught unknown exception while reading." << endl << flush;