FileDatastore.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.19 $
00022 // $Date: 2006/01/12 23:25:31 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/database/FileDatastore.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 10/98
00028 //
00029 // Description: This file contains the class implementation for FileDatastore.
00030 // FileDatastore is a concrete subclas of FE_Datastore. A FileDatastore 
00031 // object is used in the program to store/restore the geometry and state 
00032 // information in a domain at a particular instance in the analysis. The
00033 // information is stored in text files.
00034 //
00035 // What: "@(#) FileDatastore.C, revA"
00036 
00037 #include "FileDatastore.h"
00038 
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <bool.h>
00043 #include <iostream>
00044 #include <iomanip>
00045 using std::ios;
00046 using std::setiosflags;
00047 
00048 
00049 #include <FEM_ObjectBroker.h>
00050 #include <Domain.h>
00051 #include <ID.h>
00052 #include <Vector.h>
00053 #include <Matrix.h>
00054 
00055 
00056 FileDatastore::FileDatastore(const char *dataBaseName,
00057                              Domain &theDomain, 
00058                              FEM_ObjectBroker &theObjBroker) 
00059   :FE_Datastore(theDomain, theObjBroker), 
00060    data(0), sizeData(0), currentMaxInt(0), currentMaxDouble(0)
00061 {
00062   dataBase = new char [strlen(dataBaseName)+1];
00063   strcpy(dataBase, dataBaseName);
00064 
00065   this->resizeDouble(1024);
00066 }
00067 
00068 FileDatastore::~FileDatastore() 
00069 {
00070 
00071   if (data != 0)
00072     delete [] data;
00073 
00074 
00075   //  while (theIDFilesIter != theIDFiles.end()) {
00076   //    theIDFilesIter++;
00077   // }
00078 
00079   for (theIDFilesIter = theIDFiles.begin(); theIDFilesIter != theIDFiles.end(); theIDFilesIter++) {
00080     FileDatastoreOutputFile *theFileStruct = theIDFilesIter->second;
00081     fstream *theFile = theFileStruct->theFile;
00082     if (theFile != 0) {
00083       theFile->close();
00084       delete theFile;
00085     }
00086     delete theFileStruct;
00087   }
00088 
00089   theIDFiles.clear();
00090 
00091   for (theMatFilesIter = theMatFiles.begin(); theMatFilesIter != theMatFiles.end(); theMatFilesIter++) {
00092     FileDatastoreOutputFile *theFileStruct = theMatFilesIter->second;
00093     fstream *theFile = theFileStruct->theFile;
00094     if (theFile != 0) {
00095       theFile->close();
00096       delete theFile;
00097     }
00098     delete theFileStruct;
00099   }
00100   theMatFiles.clear();
00101   for (theVectFilesIter = theVectFiles.begin(); theVectFilesIter != theVectFiles.end(); theVectFilesIter++) {
00102     FileDatastoreOutputFile *theFileStruct = theVectFilesIter->second;
00103     fstream *theFile = theFileStruct->theFile;
00104     if (theFile != 0) {
00105       theFile->close();
00106       delete theFile;
00107     }
00108     delete theFileStruct;
00109   }
00110   theVectFiles.clear();
00111 }
00112 
00113 
00114 int 
00115 FileDatastore::commitState(int commitTag)
00116 {
00117   int result = FE_Datastore::commitState(commitTag);
00118   if (result == commitTag) 
00119     resetFilePointers();
00120     
00121   return result;
00122 }
00123 
00124 
00125 void
00126 FileDatastore::resetFilePointers(void) {
00127 
00128   for (theIDFilesIter = theIDFiles.begin(); theIDFilesIter != theIDFiles.end(); theIDFilesIter++) {
00129     FileDatastoreOutputFile *theFileStruct = theIDFilesIter->second;
00130     fstream *theFile = theFileStruct->theFile;
00131     if (theFile != 0) {
00132       theFile->seekp(0, ios::beg);
00133       *(theIntData.dbTag) = theFileStruct->maxDbTag;
00134       theFile->write(data, sizeof(int));    
00135       theFile->close();
00136       delete theFile;
00137       theFileStruct->theFile = 0;
00138     }
00139   }
00140 
00141   for (theMatFilesIter = theMatFiles.begin(); theMatFilesIter != theMatFiles.end(); theMatFilesIter++) {
00142     FileDatastoreOutputFile *theFileStruct = theMatFilesIter->second;
00143     fstream *theFile = theFileStruct->theFile;
00144     if (theFile != 0) {
00145       theFile->seekp(0, ios::beg);
00146       *(theIntData.dbTag) = theFileStruct->maxDbTag;
00147       theFile->write(data, sizeof(int));    
00148       theFile->close();
00149       delete theFile;
00150       theFileStruct->theFile = 0;
00151     }
00152   }
00153 
00154   for (theVectFilesIter = theVectFiles.begin(); theVectFilesIter != theVectFiles.end(); theVectFilesIter++) {
00155     FileDatastoreOutputFile *theFileStruct = theVectFilesIter->second;
00156     fstream *theFile = theFileStruct->theFile;
00157     if (theFile != 0) {
00158       theFile->seekp(0, ios::beg);
00159       *(theIntData.dbTag) = theFileStruct->maxDbTag;
00160       theFile->write(data, sizeof(int));    
00161       theFile->close();
00162       delete theFile;
00163       theFileStruct->theFile = 0;
00164     }
00165   }
00166   currentCommitTag = -1;
00167 }
00168 
00169 
00170 int 
00171 FileDatastore::sendMsg(int dataTag, int commitTag, 
00172                        const Message &, 
00173                        ChannelAddress *theAddress)
00174 {
00175   opserr << "FileDatastore::sendMsg() - not yet implemented\n";
00176   return -1;
00177 }                      
00178 
00179 int 
00180 FileDatastore::recvMsg(int dataTag, int commitTag, 
00181                        Message &, 
00182                        ChannelAddress *theAddress)
00183 {
00184   opserr << "FileDatastore::recvMsg() - not yet implemented\n";
00185   return -1;
00186 }                      
00187 
00188 
00189 
00190 int 
00191 FileDatastore::sendID(int dataTag, int commitTag, 
00192                       const ID &theID, 
00193                       ChannelAddress *theAddress)
00194 {
00195   if (currentCommitTag != commitTag)
00196     this->resetFilePointers();
00197 
00198   currentCommitTag = commitTag;
00199   
00200   FileDatastoreOutputFile *theFileStruct =0;
00201   
00202   //
00203   // next we see if we already have this file; 
00204   //  if not we need to create data structure & open it
00205   //  if we have data structure, need to check file is opened (we close in a commit)
00206   //
00207 
00208   int idSize = theID.Size();
00209   int stepSize = (1 + idSize)*sizeof(int);
00210 
00211   theIDFilesIter = theIDFiles.find(idSize); 
00212   if (theIDFilesIter == theIDFiles.end()) {
00213 
00214     // we first check if we need to resize send buffer
00215     if (idSize > currentMaxInt) {
00216       if (this->resizeInt(idSize) < 0) {
00217         opserr << "FileDatastore::sendID() - failed in resizeInt()\n";
00218         return -1;
00219       }
00220     }
00221 
00222     char *fileName = new char[strlen(dataBase)+21];
00223     theFileStruct = new FileDatastoreOutputFile;
00224 
00225     if (fileName == 0 || theFileStruct == 0) {
00226       opserr << "FileDatastore::sendID() - out of memory\n";
00227       return -1;
00228     }
00229 
00230     static char intName[20];
00231     strcpy(fileName, dataBase);
00232     sprintf(intName,"%d.%d",idSize,commitTag);
00233     strcat(fileName,".IDs.");
00234     strcat(fileName,intName);
00235     
00236     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00237       opserr << "FileDatastore::sendID() - could not open file\n";
00238       delete [] fileName;
00239       return -1;
00240     } else
00241       theIDFiles.insert(MAP_FILES_TYPE(idSize, theFileStruct));
00242     
00243     delete [] fileName;
00244     
00245   } else {
00246 
00247     theFileStruct = theIDFilesIter->second;
00248     
00249     // make sure not close from a last commit
00250     if (theFileStruct->theFile == 0) {
00251       
00252       if (idSize > currentMaxInt) {
00253         if (this->resizeInt(idSize) < 0) {
00254           opserr << "FileDatastore::sendID() - failed in resizeInt()\n";
00255           return -1;
00256         }
00257       }
00258       char *fileName = new char[strlen(dataBase)+21];
00259       static char intName[20];
00260       strcpy(fileName, dataBase);
00261       sprintf(intName,"%d.%d",idSize,commitTag);
00262       strcat(fileName,".IDs.");
00263       strcat(fileName,intName);
00264       
00265       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00266         opserr << "FileDatastore::sendID() - could not open file\n";
00267         delete [] fileName;
00268         return -1;
00269 
00270       }
00271       delete [] fileName;
00272     }
00273   }
00274 
00275   //
00276   // find location in file to place the data
00277   //
00278 
00279   fstream *theStream = theFileStruct->theFile;
00280   bool found = false;  
00281   STREAM_POSITION_TYPE pos = theStream->tellg();  
00282   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
00283   
00284   // we first check if the data can go at the end of the file
00285   // true if commitTag larger than any we have encountered so far
00286 
00287   if (theFileStruct->maxDbTag < dataTag)  {
00288     pos = fileEnd;
00289     found = true;
00290     theFileStruct->maxDbTag = dataTag;
00291   } 
00292   
00293   // try current location    
00294   if (pos < fileEnd && found == false) {
00295 // #ifdef _WIN32
00296     // must be a bug in the vc compiler! .. we are here already tellg() above!!
00297     theStream->seekg(pos, ios::beg);
00298 // #endif
00299     theStream->read(data, stepSize);
00300     if (*(theIntData.dbTag) == dataTag ) { 
00301       found = true;
00302     }
00303   }
00304   
00305   // we have to search from the beginning of the file  
00306   if (found == false) {
00307     *(theIntData.dbTag) = -1;
00308     pos = sizeof(int);
00309     theStream->seekg(pos, ios::beg);
00310     while (pos < fileEnd && found == false) {
00311       theStream->read(data, stepSize);
00312       
00313       if (*(theIntData.dbTag) == dataTag) 
00314         found = true;
00315       else 
00316         pos += stepSize;
00317     }
00318     
00319     if (found == false) {
00320       pos = fileEnd;
00321     }
00322   }
00323   
00324   //
00325   // we now place the data to be sent into our buffer
00326   //
00327   
00328   *(theIntData.dbTag) = dataTag;
00329   for (int i=0; i<idSize; i++)
00330     theIntData.data[i] = theID(i);
00331   
00332   //
00333   // we now write the data
00334   //
00335   
00336   theStream->seekp(pos, ios::beg); // reset so can go write at the end
00337   
00338   theStream->write(data, stepSize);
00339   if (theStream->bad()) {
00340     opserr << "FileDatastore::sendID() - error writing to file\n";
00341     return -1;
00342   }
00343   
00344   // update the size of file if we have added to eof
00345   if (fileEnd <= pos) 
00346     theFileStruct->fileEnd = pos + stepSize; 
00347   
00348   //opserr << "WROTE: " << dataTag << " " << pos << endln;
00349   
00350   return 0;
00351 }                      
00352 
00353 int 
00354 FileDatastore::recvID(int dataTag, int commitTag, 
00355                       ID &theID, 
00356                       ChannelAddress *theAddress)    
00357 {
00358   if (currentCommitTag != commitTag)
00359     this->resetFilePointers();
00360 
00361   currentCommitTag = commitTag;
00362   
00363   FileDatastoreOutputFile *theFileStruct;
00364   
00365   //
00366   // next we see if we already have this file; 
00367   //  if not we need to create data structure & open it
00368   //  if we have data structure, need to check file is opened (we close in a commit)
00369   //
00370 
00371   int idSize = theID.Size();
00372   int stepSize = (1 + idSize)*sizeof(int);
00373 
00374   theIDFilesIter = theIDFiles.find(idSize); 
00375   if (theIDFilesIter == theIDFiles.end()) {
00376 
00377     // we first check if we need to resize recv buffer
00378     if (idSize > currentMaxInt) {
00379       if (this->resizeInt(idSize) < 0) {
00380         opserr << "FileDatastore::recvID() - failed in resizeInt()\n";
00381         return -1;
00382       }
00383     }
00384 
00385     char *fileName = new char[strlen(dataBase)+21];
00386     theFileStruct = new FileDatastoreOutputFile;
00387 
00388     if (fileName == 0 || theFileStruct == 0) {
00389       opserr << "FileDatastore::recvID() - out of memory\n";
00390       return -1;
00391     }
00392 
00393     static char intName[20];
00394     strcpy(fileName, dataBase);
00395     sprintf(intName,"%d.%d",idSize,commitTag);
00396     strcat(fileName,".IDs.");
00397     strcat(fileName,intName);
00398     
00399     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00400       opserr << "FileDatastore::recvID() - could not open file\n";
00401       delete [] fileName;
00402       return -1;
00403     } else
00404       theIDFiles.insert(MAP_FILES_TYPE(idSize, theFileStruct));
00405 
00406     delete [] fileName;
00407   } else {
00408 
00409     theFileStruct = theIDFilesIter->second;
00410 
00411     // make sure not close from a last commit
00412     if (theFileStruct->theFile == 0) {
00413 
00414       if (idSize > currentMaxInt) {
00415         if (this->resizeInt(idSize) < 0) {
00416           opserr << "FileDatastore::recvID() - failed in resizeInt()\n";
00417           return -1;
00418         }
00419       }
00420       char *fileName = new char[strlen(dataBase)+21];
00421       static char intName[20];
00422       strcpy(fileName, dataBase);
00423       sprintf(intName,"%d.%d",idSize,commitTag);
00424       strcat(fileName,".IDs.");
00425       strcat(fileName,intName);
00426       
00427       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00428         opserr << "FileDatastore::recvID() - could not open file\n";
00429         delete [] fileName;
00430         return -1;
00431       }
00432       delete [] fileName;
00433     } 
00434   }
00435 
00436   fstream *theStream = theFileStruct->theFile;
00437   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
00438   STREAM_POSITION_TYPE pos = theStream->tellg();
00439   
00440   //
00441   // find location in file to place the data
00442   //
00443   
00444   bool found = false;  
00445 
00446   // we try the current file position first
00447 
00448   if (pos < fileEnd) {
00449     theStream->read(data, stepSize);
00450     if (*(theIntData.dbTag) == dataTag) {
00451       found = true;
00452       pos += stepSize;
00453     } 
00454   }
00455 
00456   // we must search from the beginning of the file
00457   if (found == false) {
00458     pos = sizeof(int);
00459     theStream->seekg(pos, ios::beg); 
00460     while ((pos < fileEnd) && (found == false)) {
00461       theStream->read(data, stepSize);
00462       if (*(theIntData.dbTag) == dataTag) 
00463         found = true;
00464       else 
00465         pos += stepSize;
00466     }
00467   }
00468 
00469   if (found == false) {
00470     opserr << "FileDatastore::recvID() - failed\n";
00471     return -1;
00472   }
00473 
00474   //opserr << "READ: " << dataTag << " " << pos << endln;
00475 
00476   // we now place the received data into the ID 
00477   for (int i=0; i<idSize; i++)
00478     theID(i) = theIntData.data[i];
00479 
00480   return 0;
00481 }                      
00482 
00483 
00484 
00485 
00486 int 
00487 FileDatastore::sendMatrix(int dataTag, int commitTag, 
00488                       const Matrix &theMatrix, 
00489                       ChannelAddress *theAddress)
00490 {
00491 
00492   if (currentCommitTag != commitTag)
00493     this->resetFilePointers();
00494 
00495   currentCommitTag = commitTag;
00496   
00497   FileDatastoreOutputFile *theFileStruct;
00498   
00499   //
00500   // next we see if we already have this file; 
00501   //  if not we need to create data structure & open it
00502   //  if we have data structure, need to check file is opened (we close in a commit)
00503   //
00504 
00505   // we first ensure that the Matrix is not too big
00506   int noMatCols= theMatrix.noCols();
00507   int noMatRows = theMatrix.noRows();
00508   int matSize = noMatRows * noMatCols;;
00509   int stepSize = sizeof(int) + matSize*sizeof(double);
00510 
00511   theMatFilesIter = theMatFiles.find(matSize); 
00512   if (theMatFilesIter == theMatFiles.end()) {
00513 
00514     // we first check if we need to resize send buffer
00515     if (matSize > currentMaxDouble) {
00516       if (this->resizeDouble(matSize) < 0) {
00517         opserr << "FileDatastore::sendMatrix() - failed in resizeInt()\n";
00518         return -1;
00519       }
00520     }
00521 
00522     char *fileName = new char[strlen(dataBase)+21];
00523     theFileStruct = new FileDatastoreOutputFile;
00524 
00525     if (fileName == 0 || theFileStruct == 0) {
00526       opserr << "FileDatastore::sendMatrix() - out of memory\n";
00527       return -1;
00528     }
00529 
00530     static char intName[20];
00531     strcpy(fileName, dataBase);
00532     sprintf(intName,"%d.%d",matSize,commitTag);
00533     strcat(fileName,".MATs.");
00534     strcat(fileName,intName);
00535     
00536     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00537       opserr << "FileDatastore::sendMatrix() - could not open file\n";
00538       delete [] fileName;
00539       return -1;
00540     } else
00541       theMatFiles.insert(MAP_FILES_TYPE(matSize, theFileStruct));
00542 
00543     delete [] fileName;
00544     
00545   } else {
00546 
00547     theFileStruct = theMatFilesIter->second;
00548 
00549     // make sure not close from a last commit
00550     if (theFileStruct->theFile == 0) {
00551 
00552       if (matSize > currentMaxDouble) {
00553         if (this->resizeDouble(matSize) < 0) {
00554           opserr << "FileDatastore::sendMatrix() - failed in resizeInt()\n";
00555           return -1;
00556         }
00557       }
00558       char *fileName = new char[strlen(dataBase)+21];
00559       static char intName[20];
00560       strcpy(fileName, dataBase);
00561       sprintf(intName,"%d.%d",matSize,commitTag);
00562       strcat(fileName,".MATs.");
00563       strcat(fileName,intName);
00564       
00565       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00566         opserr << "FileDatastore::sendMatrix() - could not open file\n";
00567         delete [] fileName;
00568         return -1;
00569       }
00570 
00571       delete [] fileName;
00572     }
00573   }
00574 
00575   //
00576   // find location in file to place the data
00577   //
00578   
00579   fstream *theStream = theFileStruct->theFile;
00580   bool found = false;  
00581   STREAM_POSITION_TYPE pos = theStream->tellg();  
00582   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
00583   
00584   // we first check if the data can go at the end of the file
00585   // true if commitTag larger than any we have encountered so far
00586   
00587   if (theFileStruct->maxDbTag < dataTag)  {
00588     pos = fileEnd;
00589     found = true;
00590     theFileStruct->maxDbTag = dataTag;
00591   } 
00592   
00593   // try current location    
00594   if (pos < fileEnd && found == false) {
00595 // #ifdef _WIN32
00596     // must be a bug in the vc compiler! .. we are here already tellg() above!!
00597     theStream->seekg(pos, ios::beg);
00598 // #endif
00599     theStream->read(data, stepSize);
00600     if (*(theIntData.dbTag) == dataTag ) { 
00601       found = true;
00602     }
00603   }
00604   
00605   // we have to search from the beginning of the file  
00606   if (found == false) {
00607     *(theIntData.dbTag) = -1;
00608     pos = sizeof(int);
00609     theStream->seekg(pos, ios::beg);
00610     while (pos < fileEnd && found == false) {
00611       theStream->read(data, stepSize);
00612       
00613       if (*(theIntData.dbTag) == dataTag) 
00614         found = true;
00615       else 
00616         pos += stepSize;
00617     }
00618     
00619     if (found == false) {
00620       pos = fileEnd;
00621     }
00622   }
00623 
00624   //
00625   // we now place the data to be sent into our buffer
00626   //
00627 
00628   *(theDoubleData.dbTag) = dataTag;
00629   int loc=0;
00630   for (int j=0; j<noMatCols; j++)
00631     for (int k=0; k < noMatRows; k++) {
00632       theDoubleData.data[loc] = theMatrix(k,j);
00633       loc++;
00634     }  
00635 
00636   //
00637   // we now write the data
00638   //
00639 
00640   theStream->seekp(pos, ios::beg); // reset so can go write at the end
00641   theStream->write(data, stepSize);
00642   
00643   // update the size of file if we have added to eof
00644   if (theFileStruct->fileEnd <= pos)
00645     theFileStruct->fileEnd += stepSize;  
00646 
00647   return 0;
00648 }                      
00649 
00650 
00651 
00652 
00653 int 
00654 FileDatastore::recvMatrix(int dataTag, int commitTag, 
00655                       Matrix &theMatrix, 
00656                       ChannelAddress *theAddress)    
00657 {
00658 
00659   if (currentCommitTag != commitTag)
00660     this->resetFilePointers();
00661 
00662   currentCommitTag = commitTag;
00663 
00664   FileDatastoreOutputFile *theFileStruct;
00665   
00666   //
00667   // next we see if we already have this file; 
00668   //  if not we need to create data structure & open it
00669   //  if we have data structure, need to check file is opened (we close in a commit)
00670   //
00671 
00672   // we first check Matrix not too big
00673   int noMatCols= theMatrix.noCols();
00674   int noMatRows = theMatrix.noRows();
00675   int matSize = noMatRows * noMatCols;;
00676   int stepSize = sizeof(int) + matSize*sizeof(double);
00677 
00678   theMatFilesIter = theMatFiles.find(matSize); 
00679   if (theMatFilesIter == theMatFiles.end()) {
00680 
00681     // we first check if we need to resize recv buffer
00682     if (matSize > currentMaxDouble) {
00683       if (this->resizeDouble(matSize) < 0) {
00684         opserr << "FileDatastore::recvMatrix() - failed in resizeDouble()\n";
00685         return -1;
00686       }
00687     }
00688 
00689     char *fileName = new char[strlen(dataBase)+21];
00690     theFileStruct = new FileDatastoreOutputFile;
00691 
00692     if (fileName == 0 || theFileStruct == 0) {
00693       opserr << "FileDatastore::recvMatrix() - out of memory\n";
00694       return -1;
00695     }
00696 
00697     static char intName[20];
00698     strcpy(fileName, dataBase);
00699     sprintf(intName,"%d.%d",matSize,commitTag);
00700     strcat(fileName,".MATs.");
00701     strcat(fileName,intName);
00702     
00703     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00704       opserr << "FileDatastore::recvMatrix() - could not open file\n";
00705       delete [] fileName;
00706       return -1;
00707     } else
00708       theMatFiles.insert(MAP_FILES_TYPE(matSize, theFileStruct));
00709 
00710     delete [] fileName;
00711     
00712   } else {
00713 
00714     theFileStruct = theMatFilesIter->second;
00715 
00716     // make sure not close from a last commit
00717     if (theFileStruct->theFile == 0) {
00718 
00719       if (matSize > currentMaxDouble) {
00720         if (this->resizeDouble(matSize) < 0) {
00721           opserr << "FileDatastore::recvMatrix() - failed in resizeInt()\n";
00722           return -1;
00723         }
00724       }
00725       char *fileName = new char[strlen(dataBase)+21];
00726       static char intName[20];
00727       strcpy(fileName, dataBase);
00728       sprintf(intName,"%d.%d",matSize,commitTag);
00729       strcat(fileName,".MATs.");
00730       strcat(fileName,intName);
00731       
00732       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00733         opserr << "FileDatastore::recvMatrix() - could not open file\n";
00734         delete [] fileName;
00735         return -1;
00736       }
00737 
00738       delete [] fileName;
00739     } 
00740   }
00741 
00742 
00743   fstream *theStream = theFileStruct->theFile;
00744   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
00745   STREAM_POSITION_TYPE pos = theStream->tellg();
00746   
00747   //
00748   // find location in file to place the data
00749   //
00750   
00751   bool found = false;  
00752 
00753   // we try the current file position first
00754 
00755   if (pos < fileEnd) {
00756     theStream->read(data, stepSize);
00757     if ((*(theIntData.dbTag) == dataTag)) {
00758       found = true;
00759       pos += stepSize;
00760     } 
00761   }
00762 
00763   // we must search from the beginning of the file
00764   if (found == false) {
00765     pos = sizeof(int);
00766     theStream->seekg(pos, ios::beg); 
00767     while ((pos < fileEnd) && (found == false)) {
00768       theStream->read(data, stepSize);
00769       if (*(theIntData.dbTag) == dataTag) 
00770         found = true;
00771       else 
00772         pos += stepSize;
00773     }
00774   }
00775 
00776   if (found == false) {
00777     opserr << "FileDatastore::recvMatrix() - failed\n";
00778     return -1;
00779   }
00780 
00781   int loc=0;
00782   for (int j=0; j<noMatCols; j++)
00783     for (int k=0; k < noMatRows; k++) {
00784       theMatrix(k,j) = theDoubleData.data[loc];
00785       loc++;
00786     }
00787 
00788   return 0;
00789 }                      
00790 
00791 
00792 
00793 int 
00794 FileDatastore::sendVector(int dataTag, int commitTag, 
00795                       const Vector &theVector, 
00796                       ChannelAddress *theAddress)
00797 {
00798 
00799   if (currentCommitTag != commitTag)
00800     this->resetFilePointers();
00801 
00802   currentCommitTag = commitTag;
00803   
00804   FileDatastoreOutputFile *theFileStruct;
00805   
00806   //
00807   // next we see if we already have this file; 
00808   //  if not we need to create data structure & open it
00809   //  if we have data structure, need to check file is opened (we close in a commit)
00810   //
00811 
00812   // we first ensure that the Matrix is not too big
00813   int vectSize = theVector.Size();
00814   int stepSize = sizeof(int) + vectSize*sizeof(double);
00815 
00816   theVectFilesIter = theVectFiles.find(vectSize); 
00817   if (theVectFilesIter == theVectFiles.end()) {
00818 
00819     // we first check if we need to resize send buffer
00820     if (vectSize > currentMaxDouble) {
00821       if (this->resizeDouble(vectSize) < 0) {
00822         opserr << "FileDatastore::sendVector() - failed in resizeInt()\n";
00823         return -1;
00824       }
00825     }
00826 
00827     char *fileName = new char[strlen(dataBase)+21];
00828     theFileStruct = new FileDatastoreOutputFile;
00829 
00830     if (fileName == 0 || theFileStruct == 0) {
00831       opserr << "FileDatastore::sendVector() - out of memory\n";
00832       return -1;
00833     }
00834 
00835     static char intName[20];
00836     strcpy(fileName, dataBase);
00837     sprintf(intName,"%d.%d",vectSize,commitTag);
00838     strcat(fileName,".VECs.");
00839     strcat(fileName,intName);
00840     
00841     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00842       opserr << "FileDatastore::sendVector() - could not open file\n";
00843       delete [] fileName;
00844       return -1;
00845     } else
00846       theVectFiles.insert(MAP_FILES_TYPE(vectSize, theFileStruct));
00847 
00848     delete [] fileName;
00849     
00850   } else {
00851 
00852     theFileStruct = theVectFilesIter->second;
00853 
00854     // make sure not close from a last commit
00855     if (theFileStruct->theFile == 0) {
00856 
00857       if (vectSize > currentMaxDouble) {
00858         if (this->resizeDouble(vectSize) < 0) {
00859           opserr << "FileDatastore::sendVector() - failed in resizeInt()\n";
00860           return -1;
00861         }
00862       }
00863       char *fileName = new char[strlen(dataBase)+21];
00864       static char intName[20];
00865       strcpy(fileName, dataBase);
00866       sprintf(intName,"%d.%d",vectSize,commitTag);
00867       strcat(fileName,".VECs.");
00868       strcat(fileName,intName);
00869       
00870       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
00871         opserr << "FileDatastore::sendVector() - could not open file\n";
00872         delete [] fileName;
00873         return -1;
00874       }
00875 
00876       delete [] fileName;
00877     }
00878   }
00879 
00880   //
00881   // find location in file to place the data
00882   //
00883   
00884   fstream *theStream = theFileStruct->theFile;
00885   bool found = false;  
00886   STREAM_POSITION_TYPE pos = theStream->tellg();  
00887   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
00888   
00889   // we first check if the data can go at the end of the file
00890   // true if commitTag larger than any we have encountered so far
00891   found = false;
00892   
00893   
00894   if (theFileStruct->maxDbTag < dataTag)  {
00895     pos = fileEnd;
00896     found = true;
00897     theFileStruct->maxDbTag = dataTag;
00898   } 
00899 
00900   
00901   // try current location    
00902   if (pos < fileEnd && found == false) {
00903 // #ifdef _WIN32
00904     // must be a bug in the vc compiler! .. we are here already tellg() above!!
00905     theStream->seekg(pos, ios::beg);
00906 // #endif
00907     theStream->read(data, stepSize);
00908     if (*(theIntData.dbTag) == dataTag ) { 
00909       found = true;
00910     }
00911   }
00912   
00913   // we have to search from the beginning of the file  
00914   if (found == false) {
00915     *(theIntData.dbTag) = -1;
00916     pos = sizeof(int);
00917     theStream->seekg(pos, ios::beg);
00918     while (pos < fileEnd && found == false) {
00919       theStream->read(data, stepSize);
00920       
00921       if (*(theIntData.dbTag) == dataTag) 
00922         found = true;
00923       else 
00924         pos += stepSize;
00925     }
00926     
00927     if (found == false) {
00928       pos = fileEnd;
00929     }
00930   }
00931 
00932   //
00933   // we now place the data to be sent into our buffer
00934   //
00935 
00936   *(theDoubleData.dbTag) = dataTag;
00937   for (int i=0; i<vectSize; i++)
00938     theDoubleData.data[i] = theVector(i);
00939 
00940   //
00941   // we now write the data
00942   //
00943 
00944   theStream->seekp(pos, ios::beg); // reset so can go write at the end
00945   theStream->write(data, stepSize);
00946   
00947   // update the size of file if we have added to eof
00948   if (theFileStruct->fileEnd <= pos)
00949     theFileStruct->fileEnd += stepSize;  
00950 
00951   return 0;
00952 }                      
00953 
00954 int 
00955 FileDatastore::recvVector(int dataTag, int commitTag, 
00956                       Vector &theVector, 
00957                       ChannelAddress *theAddress)    
00958 {
00959 
00960   if (currentCommitTag != commitTag)
00961     this->resetFilePointers();
00962 
00963   currentCommitTag = commitTag;
00964 
00965   FileDatastoreOutputFile *theFileStruct;
00966   
00967   //
00968   // next we see if we already have this file; 
00969   //  if not we need to create data structure & open it
00970   //  if we have data structure, need to check file is opened (we close in a commit)
00971   //
00972 
00973   // we first check Vector not too big
00974   int vectSize = theVector.Size();
00975   int stepSize = sizeof(int) + vectSize*sizeof(double);
00976 
00977   theVectFilesIter = theVectFiles.find(vectSize); 
00978   if (theVectFilesIter == theVectFiles.end()) {
00979 
00980     // we first check if we need to resize recv buffer
00981     if (vectSize > currentMaxDouble) {
00982       if (this->resizeDouble(vectSize) < 0) {
00983         opserr << "FileDatastore::recvVectrix() - failed in resizeDouble()\n";
00984         return -1;
00985       }
00986     }
00987 
00988     char *fileName = new char[strlen(dataBase)+21];
00989     theFileStruct = new FileDatastoreOutputFile;
00990 
00991     if (fileName == 0 || theFileStruct == 0) {
00992       opserr << "FileDatastore::recvVectrix() - out of memory\n";
00993       return -1;
00994     }
00995 
00996     static char intName[20];
00997     strcpy(fileName, dataBase);
00998     sprintf(intName,"%d.%d",vectSize,commitTag);
00999     strcat(fileName,".VECs.");
01000     strcat(fileName,intName);
01001     
01002     if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
01003       opserr << "FileDatastore::recvVectrix() - could not open file\n";
01004       delete [] fileName;
01005       return -1;
01006     } else
01007       theVectFiles.insert(MAP_FILES_TYPE(vectSize, theFileStruct));
01008 
01009     delete [] fileName;
01010     
01011   } else {
01012 
01013     theFileStruct = theVectFilesIter->second;
01014 
01015     // make sure not close from a last commit
01016     if (theFileStruct->theFile == 0) {
01017 
01018       if (vectSize > currentMaxDouble) {
01019         if (this->resizeDouble(vectSize) < 0) {
01020           opserr << "FileDatastore::recvVectrix() - failed in resizeInt()\n";
01021           return -1;
01022         }
01023       }
01024       char *fileName = new char[strlen(dataBase)+21];
01025       static char intName[20];
01026       strcpy(fileName, dataBase);
01027       sprintf(intName,"%d.%d",vectSize,commitTag);
01028       strcat(fileName,".VECs.");
01029       strcat(fileName,intName);
01030       
01031       if (this->openFile(fileName, theFileStruct, stepSize) < 0) {
01032         opserr << "FileDatastore::recvVectrix() - could not open file\n";
01033         delete [] fileName;
01034         return -1;
01035       }
01036 
01037       delete [] fileName;
01038     } 
01039   }
01040 
01041   fstream *theStream = theFileStruct->theFile;
01042   STREAM_POSITION_TYPE fileEnd = theFileStruct->fileEnd;
01043   STREAM_POSITION_TYPE pos = theStream->tellg();
01044   
01045   //
01046   // find location in file to place the data
01047   //
01048   
01049   bool found = false;  
01050 
01051   // we try the current file position first
01052 
01053   if (pos < fileEnd) {
01054     theStream->read(data, stepSize);
01055     if ((*(theIntData.dbTag) == dataTag)) {
01056       found = true;
01057       pos += stepSize;
01058     } 
01059   }
01060 
01061   // we must search from the beginning of the file
01062   if (found == false) {
01063     pos = sizeof(int);
01064     theStream->seekg(pos, ios::beg); 
01065     while ((pos < fileEnd) && (found == false)) {
01066       theStream->read(data, stepSize);
01067       if (*(theIntData.dbTag) == dataTag) 
01068         found = true;
01069       else 
01070         pos += stepSize;
01071     }
01072   }
01073 
01074   if (found == false) {
01075     opserr << "FileDatastore::recvVector() - failed\n";
01076     return -1;
01077   }
01078 
01079   for (int i=0; i<vectSize; i++)
01080     theVector(i) = theDoubleData.data[i];
01081 
01082   return 0;
01083 }                      
01084 
01085 
01086 #include <fstream>
01087 using std::ofstream;
01088 using std::cerr;
01089 
01090 
01091 int 
01092 FileDatastore::createTable(const char *tableName, int numColumns, char *columns[])
01093 {
01094   // open the file
01095   int res = 0;
01096   char *fileName = new char[strlen(tableName) + strlen(dataBase) + 10];
01097   if (fileName == 0) {
01098     opserr << "FileDatastore::insertData - out of memory; failed to open file: " << fileName << endln;
01099     return -1;
01100   }
01101 
01102   strcpy(fileName, dataBase);    
01103   strcat(fileName,".");
01104   strcat(fileName, tableName);
01105 
01106   ofstream table;
01107   table.open(fileName, ios::out | ios::trunc); 
01108 
01109   if (table.bad() == true || table.is_open() == false) {
01110     opserr << "FileDatastore::insertData - failed to open file: " << fileName << endln;
01111     delete [] fileName;
01112     res = -1;
01113     
01114   } 
01115 
01116   // write the data
01117   for (int i=0; i<numColumns; i++) {
01118     table << columns[i] << "\t"; 
01119   }
01120   table << "\n";
01121   table.close();
01122 
01123   delete [] fileName;
01124 
01125   return res;
01126 }
01127 
01128 int 
01129 FileDatastore::insertData(const char *tableName, char *columns[], 
01130                           int commitTag, const Vector &data)
01131 {
01132   // open the file
01133   char *fileName = new char[strlen(tableName) + strlen(dataBase) + 10];
01134   if (fileName == 0) {
01135     opserr << "FileDatastore::insertData - out of memory; failed to open file: " << fileName << endln;
01136     return -1;
01137   }
01138 
01139   strcpy(fileName, dataBase);    
01140   strcat(fileName,".");
01141   strcat(fileName, tableName);
01142 
01143   ofstream table;
01144   table.open(fileName, ios::app); 
01145   if (table.bad() == true || table.is_open() == false) {
01146     opserr << "FileDatastore::insertData - failed to open file: " << fileName << endln;
01147     delete [] fileName;
01148     return -1;
01149   }
01150 
01151   table << setiosflags(ios::scientific);
01152   table << std::setprecision(16);
01153 
01154   // write the data
01155   for (int i=0; i<data.Size(); i++) {
01156     table << data(i) << "\t";
01157   }
01158   
01159   table << "\n";
01160   table.close();
01161 
01162   delete [] fileName;
01163   return 0;
01164 }
01165 
01166 
01167 int 
01168 FileDatastore::getData(const char *tableName, char *columns[], int commitTag, Vector &data)
01169 {
01170   return 0;
01171 }
01172 
01173 
01174 
01175 /*******************************************************************
01176  *              MISC METHODS & FUNCTONS FOR OPENING THE FILE       *
01177  *******************************************************************/
01178 
01179 int
01180 FileDatastore::openFile(char *fileName, FileDatastoreOutputFile *theFileStruct, int dataSize)
01181 {
01182   fstream *res = new fstream();
01183   if (res == 0) {
01184     opserr << "FileDatastore::openFile - out of memory; failed to open file: " << fileName << endln;
01185     return 0;
01186   }
01187 
01188   res->open(fileName, ios::in | ios::out | ios::binary); 
01189 
01190   // if file did not exist, need to pass trunc flag to open it
01191   if (res->bad() == true || res->is_open() == false) {
01192     // delete & new again for unix gcc compiler to work!
01193     delete res;
01194     res = new fstream();
01195     if (res == 0) {
01196       opserr << "FileDatastore::openFile - out of memory; failed to open file: " << fileName << endln;
01197       theFileStruct->theFile = res;
01198       return -1;
01199     }
01200     res->open(fileName, ios::in | ios::out | ios::trunc | ios::binary);   
01201   }
01202 
01203   if (res->bad() == true || res->is_open() == false) {
01204     opserr << "FATAL - FileDatastore::openFile() - could not open file " << fileName << endln;
01205     delete res;
01206     theFileStruct->theFile = 0;
01207     return -1;
01208   }
01209 
01210   // set the position for writing to eof
01211   res->seekp(0,ios::end);  
01212   STREAM_POSITION_TYPE fileEnd = res->tellp();
01213   int maxDataTag = 0;
01214   
01215   if (fileEnd == 0 || fileEnd == -1) {
01216     *(theIntData.dbTag) = maxDataTag;
01217     res->write(data, sizeof(int));    
01218     fileEnd = sizeof(int);
01219     maxDataTag = -1;
01220   } else {
01221     res->seekg(0, ios::beg);  
01222     res->read(data, sizeof(int));
01223     maxDataTag = *(theIntData.dbTag);
01224   }
01225 
01226   // move to start of data part
01227   res->seekp(sizeof(int), ios::beg);
01228   res->seekg(sizeof(int), ios::beg);
01229 
01230   // fill in the structure data
01231   theFileStruct->theFile = res;
01232   theFileStruct->fileEnd = fileEnd;
01233 
01234   theFileStruct->maxDbTag = maxDataTag;               
01235 
01236   return 0;
01237 }
01238 
01239 int 
01240 FileDatastore::resizeInt(int newSize) {
01241   int sizeOfChar = sizeof(char);
01242   int sizeOfInt = sizeof(int);
01243   int sizeOfDouble = sizeof(double);  
01244   newSize = (newSize+1)*sizeOfInt/sizeOfChar;
01245 
01246   if (newSize < sizeData)
01247     return 0; // already big enough
01248 
01249   if (newSize <= 0) {
01250     opserr << "FileDatastore::resizeInt(int newSize) - invalidSize " << newSize << endln;
01251     return -1; // invalid size
01252   }
01253 
01254   if (data != 0)
01255     delete [] data;
01256 
01257   data = new char[newSize];
01258   if (data == 0) {
01259     opserr << "FileDatastore::resizeInt(int newSize) - out of memory for size: " << newSize << endln;
01260     return -1;
01261   }
01262 
01263   sizeData = newSize;
01264 
01265   currentMaxInt = (sizeData/sizeOfChar-sizeOfInt)/sizeOfInt;
01266   currentMaxDouble = (sizeData/sizeOfChar-sizeOfInt)/sizeOfDouble;  
01267   char *dataPtr = &data[sizeof(int)];
01268   theIntData.dbTag = (int *)data;
01269   theIntData.data = (int *)dataPtr;
01270   theDoubleData.dbTag = (int *)data;
01271   theDoubleData.data = (double *)dataPtr;
01272 
01273   return 0;
01274 }
01275 
01276 int
01277 FileDatastore::resizeDouble(int newSize) {
01278   int sizeOfChar = sizeof(char);
01279   int sizeOfInt = sizeof(int);
01280   int sizeOfDouble = sizeof(double);  
01281   newSize = (newSize*sizeOfDouble+sizeOfInt)/sizeOfChar;
01282 
01283   if (newSize < sizeData)
01284     return 0; // already big enough
01285 
01286   if (newSize <= 0) {
01287     opserr << "FileDatastore::resizeInt(int newSize) - invalidSize " << newSize << endln;
01288     return -1; // invalid size
01289   }
01290 
01291   if (data != 0)
01292     delete [] data;
01293 
01294   data = new char[newSize];
01295   if (data == 0) {
01296     opserr << "FileDatastore::resizeInt(int newSize) - out of memory for size: " << newSize << endln;
01297     return -1;
01298   }
01299 
01300   sizeData = newSize;
01301 
01302   currentMaxInt = (sizeOfChar*sizeData-sizeOfInt)/sizeOfInt;
01303   currentMaxDouble = (sizeOfChar*sizeData-sizeOfInt)/sizeOfDouble;  
01304   char *dataPtr = &data[sizeof(int)];
01305   theIntData.dbTag = (int *)data;
01306   theIntData.data = (int *)(dataPtr);
01307   theDoubleData.dbTag = (int *)data;
01308   theDoubleData.data = (double *)(dataPtr);
01309   return 0;
01310 }

Generated on Mon Oct 23 15:05:00 2006 for OpenSees by doxygen 1.5.0