Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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.1.1.1 $
00022 // $Date: 2000/09/15 08:23:17 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/database/FileDatastore.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/database/FileDatastore.C
00027 //
00028 // Written: fmk 
00029 // Created: 10/98
00030 // Revision: A
00031 //
00032 // Description: This file contains the class implementation for FileDatastore.
00033 // FileDatastore is a concrete subclas of FE_Datastore. A FileDatastore 
00034 // object is used in the program to store/restore the geometry and state 
00035 // information in a domain at a particular instance in the analysis. The
00036 // information is stored in text files.
00037 //
00038 // What: "@(#) FileDatastore.C, revA"
00039 
00040 #include "FileDatastore.h"
00041 #include <iostream.h>
00042 #include <fstream.h>
00043 #include <string.h>
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <bool.h>
00047 
00048 #include <MovableObject.h>
00049 #include <FEM_ObjectBroker.h>
00050 #include <Domain.h>
00051 #include <ID.h>
00052 #include <Vector.h>
00053 #include <Matrix.h>
00054 
00055 //void itoa(int x, char *str);
00056 
00057 FileDatastore::FileDatastore(char *dataBaseName,
00058         Domain &theDomain, 
00059         FEM_ObjectBroker &theObjBroker) 
00060   :FE_Datastore(theDomain, theObjBroker), dbTag(0),
00061    ids(0), vects(0), mats(0)
00062 {
00063   strcpy(dataBase, dataBaseName);
00064 
00065   ids = (fstream **)malloc(maxIDsize*sizeof(fstream *));
00066   vects = (fstream **)malloc(maxVectSize*sizeof(fstream *));
00067   mats = (fstream **)malloc(maxMatSize*sizeof(fstream *));
00068 
00069   if (ids == 0 || vects == 0 || mats == 0) {
00070     cerr << "FileDatastore::FileDatastore() - ran out of memory\n";
00071     exit(-1);
00072   }
00073 
00074   for (int i=0; i<maxIDsize; i++) {
00075     ids[i] = 0;
00076     fileEnds.ids[i] = 0;    
00077     filePos.ids[i] = 0;    
00078     fileCommitTags.ids[i] = 0;    
00079     fileDbTags.ids[i] = 0;        
00080   }
00081   for (int j=0; j<maxVectSize; j++) {
00082     vects[j] = 0;
00083     fileEnds.vects[j] = 0;
00084     filePos.vects[j] = 0;
00085     fileCommitTags.vects[j] = 0;
00086     fileDbTags.vects[j] = 0;    
00087   }
00088   for (int k=0; k<maxMatSize; k++) {
00089     mats[k] = 0;
00090     fileEnds.mats[k] = 0;
00091     filePos.mats[k] = 0;
00092     fileCommitTags.mats[k] = 0;
00093     fileDbTags.mats[k] = 0;    
00094   }
00095 }
00096 
00097 FileDatastore::~FileDatastore() 
00098 {
00099 
00100   for (int i=0; i<maxIDsize; i++) 
00101     if (ids[i] != 0) ids[i]->close();
00102   for (int j=0; j<maxVectSize; j++)
00103     if (vects[j] != 0) vects[j]->close();
00104   for (int k=0; k<maxMatSize; k++)
00105     if (mats[k] != 0) mats[k]->close();
00106   
00107   free ((void *) ids);
00108   free ((void *) vects);
00109   free ((void *) mats);
00110 }
00111 
00112 int
00113 FileDatastore::getDbTag(void)
00114 {
00115   dbTag++;
00116   return dbTag;
00117 }
00118 
00119 /********************************************************************
00120  *                   CHANNEL METHODS  THAT DO NOTHING               *
00121  ********************************************************************/
00122 
00123 char *
00124 FileDatastore::addToProgram(void)
00125 {
00126   return 0;
00127 }
00128 
00129 int 
00130 FileDatastore::setUpShadow(void)
00131 {
00132   return 0;
00133 }
00134 
00135 int 
00136 FileDatastore::setUpActor(void)
00137 {
00138   return 0;
00139 }
00140 
00141 int 
00142 FileDatastore::setNextAddress(const ChannelAddress &otherChannelAddress)
00143 {
00144   return 0;
00145 }
00146 
00147 
00148 ChannelAddress *
00149 FileDatastore::getLastSendersAddress(void)
00150 {
00151   return 0;
00152 }
00153 
00154 
00155 int 
00156 FileDatastore::commitState(int commitTag)
00157 {
00158     int result = FE_Datastore::commitState(commitTag);
00159 
00160     // if sucessfull, we close the files to flush the buffers
00161     if (result == commitTag) {
00162  for (int i=0; i<maxIDsize; i++) 
00163      if (ids[i] != 0) {
00164   ids[i]->close();
00165   ids[i] = 0;
00166      }
00167  for (int j=0; j<maxVectSize; j++)
00168      if (vects[j] != 0) {
00169   vects[j]->close();
00170   vects[j] = 0;
00171      }
00172  for (int k=0; k<maxMatSize; k++)
00173      if (mats[k] != 0) {
00174   mats[k]->close(); 
00175   mats[k] = 0;
00176      }
00177     }
00178 
00179     return result;
00180 }
00181 
00182 int 
00183 FileDatastore::sendObj(int commitTag,
00184          MovableObject &theObject, 
00185          ChannelAddress *theAddress)
00186 {
00187   return theObject.sendSelf(commitTag, *this);
00188 }
00189 
00190 int 
00191 FileDatastore::recvObj(int commitTag,
00192          MovableObject &theObject, 
00193          FEM_ObjectBroker &theNewBroker,
00194          ChannelAddress *theAddress)
00195 {
00196   return theObject.recvSelf(commitTag, *this, theNewBroker);
00197 }
00198 
00199   
00200 int 
00201 FileDatastore::sendMsg(int dataTag, int commitTag, 
00202          const Message &, 
00203          ChannelAddress *theAddress)
00204 {
00205   cerr << "FileDatastore::sendMsg() - not yet implemented\n";
00206   return -1;
00207 }         
00208 
00209 int 
00210 FileDatastore::recvMsg(int dataTag, int commitTag, 
00211          Message &, 
00212          ChannelAddress *theAddress)
00213 {
00214   cerr << "FileDatastore::recvMsg() - not yet implemented\n";
00215   return -1;
00216 }         
00217 
00218 
00219 int 
00220 FileDatastore::sendMatrix(int dataTag, int commitTag, 
00221         const Matrix &theMatrix, 
00222         ChannelAddress *theAddress)
00223 {
00224 
00225   // we first ensure that the Matrix is not too big
00226   int noMatCols= theMatrix.noCols();
00227   int noMatRows = theMatrix.noRows();
00228   int matSize = noMatRows * noMatCols;;
00229 
00230   if (matSize >= maxMatSize) {
00231     cerr << "FileDatastore::sendMatrix() - the database does not deal ";
00232     cerr << "with Matrixs of this size " << matSize << endl;
00233     return -1;
00234   }
00235 
00236   // open a file if not already opened
00237   if (mats[matSize] == 0) {
00238     char fileName[70];
00239     char intName[10];
00240     strcpy(fileName, dataBase);
00241  sprintf(intName,"%d",matSize);
00242     strcat(fileName,".Mats.");
00243     strcat(fileName,intName);
00244     mats[matSize] = this->openFile(fileName);    
00245     int loc = mats[matSize]->tellg();
00246     if (loc == -1) 
00247       loc = 0;
00248     else {
00249       int pos = 0;
00250       int stepSize = 2*sizeof(int) + matSize*sizeof(double);
00251       fstream *theStream = mats[matSize];
00252       theStream->seekg(0);
00253       int maxDataTag = 0;
00254       int maxCommitTag = 0;
00255       while (pos < loc) {
00256    theStream->read((char *)&matBuffer, stepSize);
00257    if ((matBuffer.dbTag >= dataTag) && 
00258        (matBuffer.commitTag >= commitTag)) {
00259      maxDataTag = matBuffer.dbTag;
00260      maxCommitTag = matBuffer.commitTag;     
00261    }
00262    pos += stepSize;
00263       }
00264       fileCommitTags.mats[matSize] = maxCommitTag;
00265       fileDbTags.mats[matSize] = maxDataTag;          
00266       filePos.mats[matSize] = loc;
00267     }
00268     fileEnds.mats[matSize] = loc;
00269   }
00270 
00271   // we now found the location in the file to write the data
00272   fstream *theStream = mats[matSize];
00273   int fileEnd = fileEnds.mats[matSize];
00274   int stepSize = 2*sizeof(int) + matSize*sizeof(double);
00275   
00276   //
00277   // find location in file to place the data
00278   //
00279 
00280   bool found = false;  
00281   int pos = 0;
00282   
00283   // we first check if the data can go at the end of the file
00284   // true if commitTag larger than any we have encountered so far
00285   if (fileDbTags.mats[matSize] < dataTag)  {
00286       pos = fileEnd;
00287       found = true;
00288       
00289       fileCommitTags.mats[matSize] = commitTag;
00290       fileDbTags.mats[matSize] = dataTag;    
00291 
00292   // we can also add at end if current commitTag as last time we added
00293   // and the dbTag is larger than anything entered yet so far
00294   } else if ((fileDbTags.mats[matSize] == dataTag) &&
00295       (fileCommitTags.mats[matSize] < commitTag)) {
00296       
00297       pos = fileEnd;
00298       found = true;
00299       fileCommitTags.mats[matSize] = commitTag;      
00300 
00301   // we have to search from the beginning of the file
00302   } else { 
00303       theStream->seekg(0);
00304       while ((pos < fileEnd) && (found == false)) {
00305    theStream->read((char *)&matBuffer, stepSize);
00306    if ((matBuffer.dbTag == dataTag) && 
00307        (matBuffer.commitTag == commitTag)) 
00308 
00309        found = true;
00310    else
00311      pos += stepSize;
00312       }
00313       if (found == true)
00314  filePos.mats[matSize] = pos + stepSize;
00315       else
00316  filePos.mats[matSize] = pos;
00317   }
00318   
00319   // we now place the data to be sent into our buffer
00320   matBuffer.dbTag = dataTag;
00321   matBuffer.commitTag = commitTag;
00322   int i=0;
00323   for (int j=0; j<noMatCols; j++)
00324     for (int k=0; k < noMatRows; k++) {
00325       matBuffer.data[i] = theMatrix(k,j);
00326       i++;
00327     }
00328 
00329 
00330   // we now write the data
00331   if (found == true && filePos.mats[matSize] != pos)
00332     theStream->seekp(pos);
00333 
00334   theStream->write((char *)&matBuffer, stepSize);
00335 
00336   // update the size of file if we have added to eof
00337   if (fileEnd <= pos)
00338       fileEnds.mats[matSize] += stepSize;
00339   
00340   filePos.mats[matSize] = pos + stepSize;
00341   
00342   return 0;
00343 }         
00344 
00345 
00346 
00347 
00348 int 
00349 FileDatastore::recvMatrix(int dataTag, int commitTag, 
00350         Matrix &theMatrix, 
00351         ChannelAddress *theAddress)    
00352 {
00353   // we first check Matrix not too big
00354   int noMatCols= theMatrix.noCols();
00355   int noMatRows = theMatrix.noRows();
00356   int matSize = noMatRows * noMatCols;;
00357 
00358   if (matSize >= maxMatSize) {
00359     cerr << "FileDatastore::recvMatrix() - the database does not deal with Mats";
00360     cerr << " of this size " << matSize << endl;
00361     return -1;
00362   }
00363 
00364   // open the file if not already opened
00365   if (mats[matSize] == 0) {
00366     char fileName[70];
00367     char intName[10];
00368     strcpy(fileName, dataBase);
00369  sprintf(intName,"%d",matSize);
00370     //itoa(matSize, intName);
00371     strcat(fileName,".Mats.");
00372     strcat(fileName,intName);
00373     mats[matSize] = this->openFile(fileName);    
00374     int loc = mats[matSize]->tellg();
00375     if (loc == -1) 
00376       loc = 0;
00377     else {
00378       int pos = 0;
00379       int stepSize = 2*sizeof(int) + matSize*sizeof(double);
00380       fstream *theStream = mats[matSize];
00381       theStream->seekg(0);
00382       int maxDataTag = 0;
00383       int maxCommitTag = 0;
00384       while (pos < loc) {
00385    theStream->read((char *)&matBuffer, stepSize);
00386    if ((matBuffer.dbTag >= dataTag) && 
00387        (matBuffer.commitTag >= commitTag)) {
00388      maxDataTag = matBuffer.dbTag;
00389      maxCommitTag = matBuffer.commitTag;     
00390    }
00391    pos += stepSize;
00392       }
00393       fileCommitTags.mats[matSize] = maxCommitTag;
00394       fileDbTags.mats[matSize] = maxDataTag;          
00395       filePos.mats[matSize] = loc;
00396     }
00397     fileEnds.mats[matSize] = loc;
00398   }
00399   
00400   // we now read in the data unti we reach eof or find the data
00401 
00402   int stepSize = 2*sizeof(int) + matSize*sizeof(double);
00403   fstream *theStream = mats[matSize];
00404 
00405   int fileEnd = fileEnds.mats[matSize];  
00406   int pos = filePos.mats[matSize];
00407   bool found = false;
00408   
00409   // we try the current file position first
00410   if (pos < fileEnd) {
00411       theStream->read((char *)&matBuffer, stepSize);
00412       if ((matBuffer.dbTag == dataTag) && (matBuffer.commitTag == commitTag)) {
00413    found = true;
00414    filePos.mats[matSize] += stepSize;
00415       } 
00416   }
00417 
00418   // we must search from the begiing of the file
00419   if (found == false) {
00420       theStream->seekg(0);
00421       pos =0; 
00422       while ((pos < fileEnd) && (found == false)) {
00423    theStream->read((char *)&matBuffer, stepSize);
00424    if ((matBuffer.dbTag == dataTag) && (matBuffer.commitTag == commitTag))
00425        found = true;
00426    pos += stepSize;
00427       }
00428 
00429       filePos.mats[matSize] = pos;      
00430   }
00431   
00432   if (found == false) {
00433     return -1;
00434   }
00435 
00436   // we now place the received data into the ID 
00437   matBuffer.dbTag = dataTag;
00438   matBuffer.commitTag = commitTag;
00439 
00440   int i=0;
00441   for (int j=0; j<noMatCols; j++)
00442     for (int k=0; k < noMatRows; k++) {
00443       theMatrix(k,j) = matBuffer.data[i];
00444       i++;
00445     }
00446 
00447   return 0;
00448 }         
00449 
00450 
00451 
00452 int 
00453 FileDatastore::sendVector(int dataTag, int commitTag, 
00454         const Vector &theVector, 
00455         ChannelAddress *theAddress)
00456 {
00457 
00458   // we first ensure that the ID is not too big
00459   int vectSize = theVector.Size();
00460   if (vectSize >= maxVectSize) {
00461     cerr << "FileDatastore::sendVector() - the database does not deal ";
00462     cerr << "with Vectors of this size " << vectSize << endl;
00463   }
00464 
00465   // open a file if not already opened 
00466   if (vects[vectSize] == 0) {
00467     char fileName[70];
00468     char intName[10];
00469     strcpy(fileName, dataBase);
00470  sprintf(intName,"%d",vectSize);
00471 //    itoa(vectSize, intName);
00472     strcat(fileName,".Vects.");
00473     strcat(fileName,intName);
00474     vects[vectSize] = this->openFile(fileName);    
00475     int loc = vects[vectSize]->tellg();
00476     if (loc == -1) 
00477       loc = 0;
00478     else {
00479       int pos = 0;
00480       int stepSize = 2*sizeof(int) + vectSize*sizeof(double);
00481       fstream *theStream = vects[vectSize];
00482       theStream->seekg(0);
00483       int maxDataTag = 0;
00484       int maxCommitTag = 0;
00485       while (pos < loc) {
00486    theStream->read((char *)&vectBuffer, stepSize);
00487    if ((vectBuffer.dbTag >= dataTag) && 
00488        (vectBuffer.commitTag >= commitTag)) {
00489      maxDataTag = vectBuffer.dbTag;
00490      maxCommitTag = vectBuffer.commitTag;     
00491    }
00492    pos += stepSize;
00493       }
00494       fileCommitTags.vects[vectSize] = maxCommitTag;
00495       fileDbTags.vects[vectSize] = maxDataTag;          
00496       filePos.vects[vectSize] = loc;
00497     }
00498     fileEnds.vects[vectSize] = loc;
00499   }
00500 
00501   fstream *theStream = vects[vectSize];
00502   int fileEnd = fileEnds.vects[vectSize];
00503   int stepSize = 2*sizeof(int) + vectSize*sizeof(double);
00504   
00505   //
00506   // find location in file to place the data
00507   //
00508 
00509   bool found = false;  
00510   int pos = 0;
00511   
00512   // we first check if the data can go at the end of the file
00513   // true if commitTag larger than any we have encountered so far
00514   if (fileDbTags.vects[vectSize] < dataTag)  {
00515       pos = fileEnd;
00516       found = true;
00517       
00518       fileCommitTags.vects[vectSize] = commitTag;
00519       fileDbTags.vects[vectSize] = dataTag;    
00520 
00521   // we can also add at end if current commitTag as last time we added
00522   // and the dbTag is larger than anything entered yet so far
00523   } else if ((fileDbTags.vects[vectSize] == dataTag) &&
00524       (fileCommitTags.vects[vectSize] < commitTag)) {
00525       
00526       pos = fileEnd;
00527       found = true;
00528       fileCommitTags.vects[vectSize] = commitTag;      
00529 
00530   // we have to search from the beginning of the file
00531   } else { 
00532       theStream->seekg(0);
00533       while ((pos < fileEnd) && (found == false)) {
00534    theStream->read((char *)&vectBuffer, stepSize);
00535    if ((vectBuffer.dbTag == dataTag) && 
00536        (vectBuffer.commitTag == commitTag)) 
00537 
00538        found = true;
00539    else
00540      pos += stepSize;
00541       }
00542       if (found == true)
00543  filePos.vects[vectSize] = pos + stepSize; 
00544       else
00545  filePos.vects[vectSize] = pos; 
00546   }
00547 
00548   
00549   // we now place the data to be sent into our buffer
00550   vectBuffer.dbTag = dataTag;
00551   vectBuffer.commitTag = commitTag;
00552   for (int i=0; i<vectSize; i++)
00553     vectBuffer.data[i] = theVector(i);
00554 
00555   // we now write the data
00556   if (found == true && pos != filePos.vects[vectSize])
00557     theStream->seekp(pos);
00558 
00559   theStream->write((char *)&vectBuffer, stepSize);
00560 
00561   filePos.vects[vectSize] = pos + stepSize;        
00562   
00563   // update the size of file if we have added to eof
00564   if (fileEnd <= pos)
00565     fileEnds.vects[vectSize] += stepSize;
00566 
00567   return 0;
00568 }         
00569 
00570 int 
00571 FileDatastore::recvVector(int dataTag, int commitTag, 
00572         Vector &theVector, 
00573         ChannelAddress *theAddress)    
00574 {
00575   // we first check ID not too big
00576   int vectSize = theVector.Size();
00577   if (vectSize >= maxVectSize) {
00578     cerr << "FileDatastore::recvVector() - the database does not deal with Vects";
00579     cerr << " of this size " << vectSize << endl;
00580     return -1;
00581   }
00582   
00583 
00584   if (vects[vectSize] == 0) {
00585     char fileName[70];
00586     char intName[10];
00587     strcpy(fileName, dataBase);
00588   sprintf(intName,"%d",vectSize);
00589  //   itoa(vectSize, intName);
00590     strcat(fileName,".Vects.");
00591     strcat(fileName,intName);
00592     vects[vectSize] = this->openFile(fileName);    
00593     int loc = vects[vectSize]->tellg();
00594     if (loc == -1) 
00595       loc = 0;
00596     else {
00597       int pos = 0;
00598       int stepSize = 2*sizeof(int) + vectSize*sizeof(double);
00599       fstream *theStream = vects[vectSize];
00600       theStream->seekg(0);  
00601       int maxDataTag = 0;
00602       int maxCommitTag = 0;
00603       while (pos < loc) {
00604    theStream->read((char *)&vectBuffer, stepSize);
00605    if ((vectBuffer.dbTag >= dataTag) && 
00606        (vectBuffer.commitTag >= commitTag)) {
00607      maxDataTag = vectBuffer.dbTag;
00608      maxCommitTag = vectBuffer.commitTag;     
00609    }
00610    pos += stepSize;
00611       }
00612       fileCommitTags.vects[vectSize] = maxCommitTag;
00613       fileDbTags.vects[vectSize] = maxDataTag;          
00614       filePos.vects[vectSize] = loc;
00615     }
00616     fileEnds.vects[vectSize] = loc;
00617   }
00618 
00619   // we now read in the data unti we reach eof or find the data
00620   int stepSize = 2*sizeof(int) + vectSize*sizeof(double);
00621   fstream *theStream = vects[vectSize];
00622 
00623   int fileEnd = fileEnds.vects[vectSize];  
00624   int pos = filePos.vects[vectSize];
00625   bool found = false;
00626 
00627   // we try the current file position first
00628   if (pos < fileEnd) {
00629       theStream->read((char *)&vectBuffer, stepSize);
00630       if ((vectBuffer.dbTag == dataTag) && (vectBuffer.commitTag == commitTag)) {
00631    found = true;
00632    filePos.vects[vectSize] += stepSize;
00633       } 
00634   }
00635 
00636   // we must search from the begiing of the file
00637   if (found == false) {
00638       theStream->seekg(0);  
00639       pos = 0;
00640       while ((pos < fileEnd) && (found == false)) {
00641    theStream->read((char *)&vectBuffer, stepSize);
00642    if ((vectBuffer.dbTag == dataTag) && 
00643        (vectBuffer.commitTag == commitTag)) 
00644 
00645      found = true;
00646    pos += stepSize;
00647       }
00648       filePos.vects[vectSize] = pos;
00649   }
00650   
00651   if (found == false) {
00652     return -1;
00653   }
00654 
00655   // we now place the received data into the Vector
00656   vectBuffer.dbTag = dataTag;
00657   vectBuffer.commitTag = commitTag;
00658   for (int i=0; i<vectSize; i++)
00659     theVector(i) = vectBuffer.data[i];
00660 
00661   return 0;
00662 }         
00663 
00664 
00665 
00666 int 
00667 FileDatastore::sendID(int dataTag, int commitTag, 
00668         const ID &theID, 
00669         ChannelAddress *theAddress)
00670 {
00671   // we first ensure that the ID is not too big
00672   int idSize = theID.Size();
00673   if (idSize >= maxIDsize) {
00674     cerr << "FileDatastore::sendID() - the database does not deal with IDs of this size ";
00675     cerr << idSize << endl;
00676   }
00677 
00678 
00679   // open a file if not already opened
00680   if (ids[idSize] == 0) {
00681 
00682     char fileName[70];
00683     char intName[10];
00684     strcpy(fileName, dataBase);
00685  sprintf(intName,"%d",idSize);
00686 //    itoa(idSize, intName);
00687     strcat(fileName,".IDs.");
00688     strcat(fileName,intName);
00689 
00690     ids[idSize] = this->openFile(fileName);  
00691  
00692     int loc = ids[idSize]->tellg();
00693     if (loc == -1) 
00694       loc = 0;
00695     else {
00696       int pos = 0;
00697       int stepSize = (2 + idSize)*sizeof(int);
00698       fstream *theStream = ids[idSize];
00699       theStream->seekg(0);  
00700       int maxDataTag = 0;
00701       int maxCommitTag = 0;
00702       while (pos < loc) {
00703    theStream->read((char *)&idBuffer, stepSize);
00704    if ((idBuffer.dbTag >= dataTag) && 
00705        (idBuffer.commitTag >= commitTag)) {
00706      maxDataTag = idBuffer.dbTag;
00707      maxCommitTag = idBuffer.commitTag;     
00708    }
00709    pos += stepSize;
00710       }
00711       fileCommitTags.ids[idSize] = maxCommitTag;
00712       fileDbTags.ids[idSize] = maxDataTag;          
00713       filePos.ids[idSize] = loc;
00714     }
00715     fileEnds.ids[idSize] = loc;
00716   }
00717 
00718   // we now found the location in the file to write the data
00719   fstream *theStream = ids[idSize];
00720   int fileEnd = fileEnds.ids[idSize];
00721   int stepSize = (2 + idSize)*sizeof(int);
00722 
00723   //
00724   // find location in file to place the data
00725   //
00726 
00727   bool found = false;  
00728   int pos = 0;
00729 
00730   // we first check if the data can go at the end of the file
00731   // true if commitTag larger than any we have encountered so far
00732   if (fileDbTags.ids[idSize] < dataTag)  {
00733 
00734       pos = fileEnd;
00735       found = true;
00736       fileCommitTags.ids[idSize] = commitTag;
00737       fileDbTags.ids[idSize] = dataTag;    
00738 
00739   // we can also add at end if current commitTag as last time we added
00740   // and the dbTag is larger than anything entered yet so far
00741   } else if ((fileDbTags.ids[idSize] == dataTag) &&
00742       (fileCommitTags.ids[idSize] < commitTag)) {
00743       
00744       pos = fileEnd;
00745       found = true;
00746       fileCommitTags.ids[idSize] = commitTag;      
00747 
00748   // we have to search from the beginning of the file
00749   } else { 
00750       theStream->seekg(0);
00751       while ((pos < fileEnd) && (found == false)) {
00752    theStream->read((char *)&idBuffer, stepSize);
00753    if ((idBuffer.dbTag == dataTag) && 
00754        (idBuffer.commitTag == commitTag)) 
00755 
00756        found = true;
00757    else
00758      pos += stepSize;
00759       }
00760       if (found == true)
00761  filePos.ids[idSize] = pos + stepSize; 
00762       else
00763  filePos.ids[idSize] = pos; 
00764 
00765   }
00766 
00767 
00768   // we now place the data to be sent into our buffer
00769   idBuffer.dbTag = dataTag;
00770   idBuffer.commitTag = commitTag;
00771   for (int i=0; i<idSize; i++)
00772     idBuffer.data[i] = theID(i);
00773   // we now write the data
00774   if (found == true && pos != filePos.ids[idSize]) 
00775     theStream->seekp(pos);
00776 
00777   theStream->write((char *)&idBuffer, stepSize);
00778 
00779   filePos.ids[idSize] = pos + stepSize;        
00780   
00781   // update the size of file if we have added to eof
00782   if (fileEnd <= pos)
00783     fileEnds.ids[idSize] += stepSize;  
00784   
00785   return 0;
00786 }         
00787 
00788 int 
00789 FileDatastore::recvID(int dataTag, int commitTag, 
00790         ID &theID, 
00791         ChannelAddress *theAddress)    
00792 {
00793   // we first check ID not too big
00794   int idSize = theID.Size();
00795   if (idSize >= maxIDsize) {
00796     cerr << "FileDatastore::recvID() - the database does not deal with IDs";
00797     cerr << " of this size "  << idSize << endl;
00798     return -1;
00799   }
00800 
00801   // open file if not already done so
00802   if (ids[idSize] == 0) {
00803     char fileName[70];
00804     char intName[10];
00805     strcpy(fileName, dataBase);
00806  sprintf(intName,"%d",idSize);
00807 //    itoa(idSize, intName);
00808     strcat(fileName,".IDs.");
00809     strcat(fileName,intName);
00810     ids[idSize] = this->openFile(fileName);    
00811     int loc = ids[idSize]->tellg();
00812     if (loc == -1) 
00813       loc = 0;
00814     else {
00815       int pos = 0;
00816       int stepSize = (2 + idSize)*sizeof(int);
00817       fstream *theStream = ids[idSize];
00818       theStream->seekg(0);  
00819       int maxDataTag = 0;
00820       int maxCommitTag = 0;
00821       while (pos < loc) {
00822    theStream->read((char *)&idBuffer, stepSize);
00823    /*
00824    cerr << idBuffer.dbTag << " " << idBuffer.commitTag;
00825    for (int i=0; i<idSize; i++)
00826      cerr << " " << idBuffer.data[i];
00827    cerr << endl;
00828    */
00829    
00830    if ((idBuffer.dbTag >= dataTag) && 
00831        (idBuffer.commitTag >= commitTag)) {
00832      maxDataTag = idBuffer.dbTag;
00833      maxCommitTag = idBuffer.commitTag;     
00834    }
00835    pos += stepSize;
00836       }
00837       fileCommitTags.ids[idSize] = maxCommitTag;
00838       fileDbTags.ids[idSize] = maxDataTag;          
00839       filePos.ids[idSize] = loc;
00840     }
00841     fileEnds.ids[idSize] = loc;
00842   }
00843 
00844   // we now set some parameters before we go looking for the data
00845   int stepSize = (2 + idSize)*sizeof(int);
00846   fstream *theStream = ids[idSize];
00847   int fileEnd = fileEnds.ids[idSize];  
00848   int pos = filePos.ids[idSize];
00849   bool found = false;
00850 
00851   // we try the current file position first
00852   if (pos < fileEnd) {
00853       theStream->read((char *)&idBuffer, stepSize);
00854 
00855       if ((idBuffer.dbTag == dataTag) && (idBuffer.commitTag == commitTag)) {
00856    found = true;
00857    filePos.ids[idSize] += stepSize;
00858       } 
00859   }
00860 
00861   // we must search from the beginning of the file
00862   if (found == false) {
00863       pos = 0;
00864       theStream->seekg(0);  
00865 
00866       while ((pos < fileEnd) && (found == false)) {
00867    theStream->read((char *)&idBuffer, stepSize);
00868 
00869    if ((idBuffer.dbTag == dataTag) && 
00870        (idBuffer.commitTag == commitTag)) {
00871 
00872        found = true;
00873    }
00874    pos += stepSize;
00875       }
00876       filePos.ids[idSize] = pos;
00877   }  
00878 
00879   if (found == false) {
00880     return -1;
00881   }
00882 
00883   // we now place the received data into the ID 
00884   idBuffer.dbTag = dataTag;
00885   idBuffer.commitTag = commitTag;
00886   for (int i=0; i<idSize; i++)
00887     theID(i) = idBuffer.data[i];
00888 
00889   return 0;
00890 }         
00891 
00892 
00893 /*******************************************************************
00894  *              MISC METHODS & FUNCTONS FOR OPENING THE FILE       *
00895  *******************************************************************/
00896 
00897 fstream *
00898 FileDatastore::openFile(char *fileName)
00899 {
00900 #ifdef _WIN32    
00901     fstream *res = new fstream(fileName, ios::in | ios::out | ios::binary);
00902 #else
00903     fstream *res = new fstream(fileName, ios::in | ios::out);    
00904 #endif
00905     
00906     if (res == 0) {
00907  cerr << "FATAL - FileDatastore::openFile() - could not open file ";
00908  cerr << fileName << endl;
00909  exit(-1);
00910     }
00911   
00912     // set the position for writing to eof
00913     res->seekp(0,ios::end);
00914 
00915     return res;
00916 }
00917 
00918 /*
00919 char itoc(int x)
00920 {
00921  if (x == 1) return '1';
00922  if (x == 2) return '2';
00923  if (x == 3) return '3';
00924  if (x == 4) return '4';
00925  if (x == 5) return '5';
00926  if (x == 6) return '6';
00927  if (x == 7) return '7';
00928  if (x == 8) return '8';
00929  if (x == 9) return '9';
00930  return '0';
00931 }
00932 
00933 void
00934 itoa(int x, char *str)
00935 {
00936   int y=x;
00937   while (y >= 10) 
00938     y = y/10;
00939   str[0] = itoc(y);
00940   str[1] = '\0';
00941   if (x >= 10) {
00942     int z = x/10;
00943     z = x - 10*z;
00944     itoa(z,&str[1]);
00945   }
00946 }
00947 
00948 */
Copyright Contact Us