SavingLoading.cc

Go to the documentation of this file.
00001 /*
00002  * opencog/persist/file/SavingLoading.cc
00003  *
00004  * Copyright (C) 2002-2007 Novamente LLC
00005  * All Rights Reserved
00006  *
00007  * Written by Thiago Maia <thiago@vettatech.com>
00008  *            Andre Senna <senna@vettalabs.com>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU Affero General Public License v3 as
00012  * published by the Free Software Foundation and including the exceptions
00013  * at http://opencog.org/wiki/Licenses
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Affero General Public License
00021  * along with this program; if not, write to:
00022  * Free Software Foundation, Inc.,
00023  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 
00026 /* SavingLoading.cc - Saves/loads the atom network (or a subset of it) to/from
00027  * disk */
00028 
00029 #include "CompositeRenumber.h"
00030 #include "SavingLoading.h"
00031 #include "SpaceServerSavable.h"
00032 #include "TimeServerSavable.h"
00033 #include "CoreUtils.h"
00034 
00035 #include <fcntl.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <time.h>
00039 
00040 #include <opencog/util/platform.h>
00041 
00042 #include <opencog/atomspace/AtomSpaceDefinitions.h>
00043 #include <opencog/atomspace/ClassServer.h>
00044 #include <opencog/atomspace/CompositeTruthValue.h>
00045 #include <opencog/atomspace/HandleIterator.h>
00046 #include <opencog/atomspace/HandleMap.h>
00047 #include <opencog/atomspace/Link.h>
00048 #include <opencog/atomspace/Node.h>
00049 #include <opencog/atomspace/StatisticsMonitor.h>
00050 #include <opencog/atomspace/TLB.h>
00051 #include <opencog/atomspace/types.h>
00052 #include <opencog/util/Logger.h>
00053 
00054 using namespace opencog;
00055 
00056 #define FULL_NETWORK_DUMP          (1 << 0)
00057 #define ATOM_SET                   (1 << 1)
00058 #define PHYSICAL_ADDRESSING        (1 << 2)
00059 
00060 #define INDEX_REPORT_FACTOR             1.02
00061 #define POST_PROCESSING_REPORT_FACTOR   1.10
00062 
00063 int processed = 0;
00064 int total = 0;
00065 
00066 SavingLoading::SavingLoading()
00067 {
00068 }
00069 
00070 void SavingLoading::save(const char *fileName, AtomSpace& atomSpace) throw (IOException)
00071 {
00072     logger().info("Starting Memory dump");
00073 
00074     time_t start = time(NULL);
00075 
00076     // opens the file that will be modified
00077     FILE *f = fopen(fileName, "wb");
00078     if (f == NULL) {
00079         throw IOException(TRACE_INFO,
00080                           "SavingLoading - Unable to open file '%s' for writing", fileName);
00081     }
00082 
00083     AtomTable& atomTable = atomSpace.atomTable;
00084 
00085     // stores the total number of atoms in the system
00086     int atomCount = atomTable.getSize();
00087 
00088     // a flag that indicates the file format
00089     char format = FULL_NETWORK_DUMP;
00090 
00091     // writes on the file the file format and the  number of atoms
00092     fwrite(&format, sizeof(char), 1, f);
00093     fwrite(&atomCount, sizeof(int), 1, f);
00094 
00095     processed = 0;
00096     total = atomCount;
00097 
00098     // save classserver info
00099     saveClassServerInfo(f);
00100 
00101     saveNodes(f, atomTable, atomCount);
00102     saveLinks(f, atomTable, atomCount);
00103 
00104     TimeServerSavable tss;
00105     tss.setServer(&atomSpace.timeServer);
00106     tss.saveRepository(f);
00107 
00108     SpaceServerSavable sss;
00109     sss.setServer(atomSpace.spaceServer);
00110     sss.saveRepository(f);
00111 
00112     saveRepositories(f);
00113 
00114     // closes the file
00115     fclose(f);
00116 
00117     // calculates the total time that the process of saving has spent
00118     time_t duration = time(NULL) - start;
00119     logger().info("Memory dump: 100%% done (in %d second%c).",
00120                   (int) duration, duration == 1 ? '\0' : 's');
00121     fflush(stdout);
00122 }
00123 
00124 void SavingLoading::saveClassServerInfo(FILE *f)
00125 {
00126     logger().fine("SavingLoading::saveClassServerInfo");
00127     int numTypes = classserver().getNumberOfClasses();
00128 
00129     fwrite(&numTypes, sizeof(int), 1, f);
00130 
00131     for (Type i = 0; i < numTypes; i++) {
00132         int classNameLength = classserver().getTypeName(i).length();
00133         fwrite(&classNameLength, sizeof(int), 1, f);
00134         fwrite(classserver().getTypeName(i).c_str(), sizeof(char), classNameLength, f);
00135         fwrite(&i, sizeof(Type), 1, f);
00136     }
00137 }
00138 
00139 void SavingLoading::saveNodes(FILE *f, AtomTable& atomTable, int &atomCount)
00140 {
00141     logger().fine("SavingLoading::saveNodes");
00142 
00143     int numNodes = 0;
00144 
00145     // gets the position of the pointer on the file for future reference
00146     int numNodesOffset = ftell(f);
00147 
00148     // writes 0 on the file. Later, the total number of nodes will be written
00149     // here
00150     fwrite(&numNodes, sizeof(int), 1, f);
00151 
00152     // creates an iterator to iterate on all nodes
00153     HandleIterator* iter = atomTable.getHandleIterator(NODE, true);
00154 
00155     // writes nodes to file and increments node counter
00156     while (iter->hasNext()) {
00157         Handle atomHandle = iter->next();
00158         Node* node = dynamic_cast<Node*>(TLB::getAtom(atomHandle));
00159         if ( node == NULL ) {
00160             logger().error( "Trying to save a node which isn't registered at TLB. Handle %d", atomHandle.value() );
00161             continue;
00162         } // if
00163         logger().info( "Saving Node handle %d name %s", atomHandle.value(), node->toString().c_str() );
00164         writeNode(f, node);
00165         numNodes++;
00166         int percentage = (int) (100 * ((float) ++processed / (total * INDEX_REPORT_FACTOR)));
00167         if ((percentage % 10) == 0) {
00168             printf( "Memory dump: %d%% done.\r", percentage);
00169             fflush(stdout);
00170         }
00171     }
00172 
00173     delete iter;
00174 
00175     // rewind to position where number of nodes must be written
00176     fseek(f, numNodesOffset, SEEK_SET);
00177 
00178     // writes the number of nodes in the proper position
00179     fwrite(&numNodes, sizeof(int), 1, f);
00180 
00181     //updates atomCount
00182     atomCount -= numNodes;
00183 
00184     // returns the pointer back to the end of the file
00185     fseek(f, 0, SEEK_END);
00186 }
00187 
00188 void SavingLoading::saveLinks(FILE *f, AtomTable& atomTable, int &atomCount)
00189 {
00190     logger().fine("SavingLoading::saveLinks");
00191 
00192     int numLinks = 0;
00193     // gets the position of the pointer on the file for future reference
00194     int numLinksOffset = ftell(f);
00195 
00196     // writes 0 on the file. Later, the total number of links will be written
00197     // here
00198     fwrite(&numLinks, sizeof(int), 1, f);
00199 
00200     // creates a iterator to iterate on all links
00201     HandleIterator* iter = atomTable.getHandleIterator(LINK, true);
00202 
00220     std::set<Handle> linkHandles;
00221     while (iter->hasNext()) {
00222         linkHandles.insert( iter->next( ) );
00223     } // while
00224     delete iter;
00225 
00226     // writes links to file and increments link counter
00227     std::set<Handle>::iterator itLinks;
00228     for( itLinks = linkHandles.begin( ); itLinks != linkHandles.end( ); ++itLinks ) {
00229         Link* link = dynamic_cast<Link*>(TLB::getAtom(*itLinks));
00230         logger().fine( "Saving Link handle %d name %s", itLinks->value(), link->toString().c_str() );
00231         writeLink(f, link);
00232         numLinks++;
00233         printf( "Memory dump: %d%% done.\r", (int) (100 * ((float) ++processed / (total * INDEX_REPORT_FACTOR))));
00234         fflush(stdout);        
00235     } // for
00236 
00237     // rewind to position where number of links must be written
00238     fseek(f, numLinksOffset, SEEK_SET);
00239 
00240     // writes the number of links in the proper position
00241     fwrite(&numLinks, sizeof(int), 1, f);
00242 
00243     // updates the atomCount
00244     atomCount -= numLinks;
00245 
00246     // returns the pointer back to the end of the file
00247     fseek(f, 0, SEEK_END);
00248 }
00249 
00250 void SavingLoading::load(const char *fileName, AtomSpace& atomSpace) throw (RuntimeException, IOException, InconsistenceException)
00251 {
00252     clearRepositories();
00253 
00254     logger().fine("Starting Memory load");
00255 
00256     if (StatisticsMonitor::getInstance()->getAtomCount() > 0) {
00257         throw RuntimeException(TRACE_INFO,
00258                                "SavingLoading - Can only load binary image from disk into an empty atom table.");
00259     }
00260     // The above sanity check does not work if StatisticMonitor is disabled. So, makes a different check:
00261     if (atomSpace.getAtomTable().getSize() > 0) {
00262         throw RuntimeException(TRACE_INFO,
00263                                "SavingLoading - Can only load binary image from disk in a empty atom table.");
00264     }
00265 
00266     time_t start = time(NULL);
00267 
00268     // opens the file that will be read
00269     FILE *f = fopen(fileName, "rb");
00270     if (f == NULL) {
00271         throw IOException(TRACE_INFO,
00272                           "SavingLoading - Unable to open file '%s' for reading.", fileName);
00273     }
00274 
00275     // reads the file format
00276     char format;
00277     fread(&format, sizeof(char), 1, f);
00278 
00279     if (! (format & FULL_NETWORK_DUMP)) {
00280         throw RuntimeException(TRACE_INFO, "SavingLoading - invalid file format '%c'.", format);
00281     }
00282 
00283     // reads the total number of atoms. Just an idea for now.
00284     int atomCount = StatisticsMonitor::getInstance()->getAtomCount();
00285     fread(&atomCount, sizeof(int), 1, f);
00286 
00287     // creates a hash map from old handles to new ones
00288     HandleMap<Atom *> *handles = new HandleMap<Atom *>();
00289 
00290     processed = 0;
00291     total = atomCount;
00292 
00293     AtomTable& atomTable = atomSpace.atomTable;
00294 
00295     std::vector<Type> dumpToCore;
00296     loadClassServerInfo(f, dumpToCore);
00297     loadNodes(f, handles, atomTable, dumpToCore);
00298     loadLinks(f, handles, atomTable, dumpToCore);
00299 
00300     HandleMapIterator<Atom *> *it = handles->keys();
00301     while (it->hasNext()) {
00302         Atom *element = (Atom *)handles->get(it->next());
00303         updateHandles(element, handles);
00304     }
00305     delete(it);
00306 
00307     printProgress("load", (int) (100 * (((float) processed + (0.75 * ((total * INDEX_REPORT_FACTOR * POST_PROCESSING_REPORT_FACTOR) - processed))) / (total * INDEX_REPORT_FACTOR * POST_PROCESSING_REPORT_FACTOR))));
00308     fflush(stdout);
00309 
00310 
00311     TimeServerSavable tss;
00312     tss.setServer(&atomSpace.timeServer);
00313     tss.loadRepository(f, handles);
00314 
00315     SpaceServerSavable sss;
00316     sss.setServer(atomSpace.spaceServer);
00317     sss.loadRepository(f, handles);
00318 
00319     loadRepositories(f, handles);
00320 
00321     delete handles;
00322 
00323     fclose(f);
00324 
00325     // update all statistics
00326     StatisticsMonitor::getInstance()->reevaluateAllStatistics(atomTable);
00327 
00328     // calculates the total time that the process of loading has spent
00329     time_t duration = time(NULL) - start;
00330     logger().info("Memory load: 100%% done (in %d second%c).",
00331                   (int) duration, duration == 1 ? '\0' : 's');
00332     fflush(stdout);
00333 }
00334 
00335 void SavingLoading::loadClassServerInfo(FILE *f, std::vector<Type>& dumpToCore)
00336 {
00337     logger().fine("SavingLoading::loadClassServerInfo");
00338     char buffer[1 << 16];
00339     int numTypes = classserver().getNumberOfClasses();
00340 
00341     int numTypesDump;
00342     fread(&numTypesDump, sizeof(int), 1, f);
00343 
00344     dumpToCore.resize(numTypesDump);
00345     for (int i = 0; i < numTypesDump; i++) {
00346         int classNameLength;
00347         fread(&classNameLength, sizeof(int), 1, f);
00348         fread(buffer, sizeof(char), classNameLength, f);
00349         buffer[classNameLength] = '\0';
00350         Type typeDump;
00351         fread(&typeDump, sizeof(Type), 1, f);
00352 
00353         if (!classserver().isDefined(buffer)) {
00354             dumpToCore[typeDump] = numTypes + 1;
00355             logger().warn("Warning: type inconsistence found (%d-%s)", typeDump, buffer);
00356         } else {
00357             dumpToCore[typeDump] = classserver().getType(buffer);
00358         }
00359     }
00360 
00361 }
00362 
00363 void SavingLoading::loadNodes(FILE *f, HandleMap<Atom *> *handles, AtomTable& atomTable, const std::vector<Type>& dumpToCore )
00364 {
00365     logger().fine("SavingLoading::loadNodes");
00366 
00367     int numNodes;
00368     // reads the total number of nodes
00369     fread(&numNodes, sizeof(int), 1, f);    
00370 
00371     // reads each node from the file
00372     for (int i = 0; i < numNodes; i++) {
00373         Node *node = new Node(NODE, "");
00374         
00375         Type oldType;
00376         fread(&oldType, sizeof(Type), 1, f);        
00377         if (dumpToCore[oldType] > classserver().getNumberOfClasses()) {
00378             throw InconsistenceException(TRACE_INFO,
00379                                          "SavingLoading - Type inconsistence clash '%d'.", oldType );
00380         }
00381         node->type = dumpToCore[oldType];
00382         readNode(f, node, handles);
00383 
00384         atomTable.add( node );
00385         printProgress("load", (int) (100 * ((float) ++processed / (total * INDEX_REPORT_FACTOR * POST_PROCESSING_REPORT_FACTOR))));
00386         fflush(stdout);
00387     }
00388 
00389 }
00390 
00391 void SavingLoading::loadLinks(FILE *f, HandleMap<Atom *> *handles, AtomTable& atomTable, const std::vector<Type>& dumpToCore)
00392 {
00393     logger().fine("SavingLoading::loadLinks");
00394 
00395     int numLinks;
00396     // reads the total number of links
00397     fread(&numLinks, sizeof(int), 1, f);
00398 
00405     // first reads each link from the file
00406     for (int i = 0; i < numLinks; i++) {
00407         // a new link is created
00408         Link *link = new Link(LINK, std::vector<Handle>());
00409 
00410         Type oldType;
00411         fread(&oldType, sizeof(Type), 1, f);        
00412         if (dumpToCore[oldType] > classserver().getNumberOfClasses()) {
00413             throw InconsistenceException(TRACE_INFO,
00414                                          "SavingLoading - Type inconsistence clash '%d'.", oldType );
00415         }
00416         link->type = dumpToCore[oldType];
00417         readLink( f, link, handles );
00418 
00419         atomTable.add(link);
00420     } // for
00421 }
00422 
00423 void SavingLoading::updateHandles(Atom *atom, HandleMap<Atom *> *handles)
00424 {
00425     logger().fine("SavingLoading::updateHandles: atom = %p, type = %d", atom, atom->getType());
00426 
00427     // if atom uses a CompositeTruthValue, updates the version handles inside it
00428     if (atom->getTruthValue().getType() == COMPOSITE_TRUTH_VALUE) {
00429         //logger().fine("SavingLoading::updateHandles: CTV");
00430         CompositeTruthValue ctv((const CompositeTruthValue&) atom->getTruthValue());
00431         CompositeRenumber::updateVersionHandles(ctv, handles);
00432         atom->setTruthValue(ctv);        
00433     } // if
00434     
00435     // updates handles for trail
00436     if (classserver().isA(atom->type, LINK)) {
00437         Trail *t = ((Link *)atom)->getTrail();
00438         if (t->getSize()) {
00439             //logger().fine("SavingLoading::updateHandles: trails");
00440             Trail *newTrail = new Trail();
00441             for (size_t i = 0; i < t->getSize(); i++) {
00442                 Handle handle = t->getElement(i);
00443                 CoreUtils::updateHandle(&handle, handles);
00444                 newTrail->insert(handle);
00445             }
00446             ((Link *)atom)->setTrail(newTrail);
00447             //newTrail->print();
00448             delete(t);
00449         }
00450     }
00451     
00452 }
00453 
00454 void SavingLoading::writeAtom(FILE *f, Atom *atom)
00455 {
00456     logger().info("SavingLoading::writeAtom: %p (type = %d) (handle = %d)", atom, atom->getType(), TLB::getHandle(atom).value( ));
00457 
00458     // writes the atom type
00459     fwrite(&atom->type, sizeof(Type), 1, f);
00460     // writes the atom flags
00461     fwrite(&atom->flags, sizeof(char), 1, f);
00462 
00463     // writes the atom handle
00464     Handle handle = TLB::getHandle(atom);
00465     fwrite(&handle, sizeof(Handle), 1, f);
00466 
00467     // incoming references will be re-created during the loading process
00468 
00469     // writes the Attention Value
00470     writeAttentionValue(f, atom->getAttentionValue());
00471 
00472     // writes the Truth Value
00473     writeTruthValue(f, atom->getTruthValue());
00474 }
00475 
00476 void SavingLoading::readAtom(FILE *f, HandleMap<Atom *> *handles, Atom *atom)
00477 {
00478     logger().fine("SavingLoading::readAtom()");
00479 
00480 
00481     // reads the atom flags
00482     fread(&atom->flags, sizeof(char), 1, f);
00483 
00484     // reads the atom handle
00485     Handle atomHandle;
00486     fread(&atomHandle, sizeof(Handle), 1, f);
00487 
00488     if (handles != NULL) {
00489         handles->add(atomHandle, atom);
00490         logger().fine("Added handles in map: %p => %p (type = %d)", atomHandle.value(), atom, atom->getType());
00491     } else {
00492         logger().warn("No HandleMap while reading atom from file: %p (type = %d)", atom, atom->getType());
00493     }
00494 
00495     // reads AttentionValue
00496     AttentionValue *av = readAttentionValue(f);
00497     atom->setAttentionValue(*av);
00498     delete (av);
00499 
00500     TruthValue *tv = readTruthValue(f);
00501     atom->setTruthValue(*tv);
00502     delete (tv);
00503 
00504 }
00505 
00506 void SavingLoading::writeNode(FILE *f, Node *node)
00507 {
00508 
00509     writeAtom(f, node);
00510 
00511     // writes the node's name on the file
00512     int nameSize = node->name.length();
00513     fwrite(&nameSize, sizeof(int), 1, f);
00514     if (nameSize > 0) {
00515         fwrite(node->name.c_str(), sizeof(char), nameSize, f);
00516     }
00517 }
00518 
00519 void SavingLoading::readNode(FILE *f, Node* node, HandleMap<Atom *> *handles) 
00520 {
00521     logger().fine("SavingLoading::readNode()");
00522 
00523     // the atom properties of the node is read from the file
00524     readAtom(f, handles, node);
00525 
00526     // the node's name is read from the file
00527     int nameSize;
00528     fread(&nameSize, sizeof(int), 1, f);
00529     if (nameSize > 0) {
00530         char *name = new char[nameSize+1];
00531         fread(name, sizeof(char), nameSize, f);
00532         name[nameSize] = '\0';
00533         node->name = name;
00534         delete[](name);
00535     }
00536 
00537 }
00538 
00539 void SavingLoading::writeLink(FILE *f, Link *link)
00540 {
00541     logger().fine("writeLink(): %s", link->toString().c_str());
00542 
00543     //link->getTrail()->print();
00544 
00545     writeAtom(f, link);
00546 
00547     // the link's arity is written on the file
00548     Arity arity = link->getArity();
00549     fwrite(&arity, sizeof(Arity), 1, f);
00550 
00551     // the link's outgoing set is written on the file
00552     for (int i = 0; i < arity; i++) {
00553         //logger().fine("writeLink(): outgoing[%d] => %p: %s", i, link->outgoing[i], link->outgoing[i]->toString().c_str());
00554         fwrite(&(link->outgoing[i]), sizeof(Handle), 1, f);
00555     }
00556 
00557     // the trail
00558     Trail *trail = link->getTrail();
00559 
00560     int trailSize = trail->getSize();
00561     fwrite(&trailSize, sizeof(int), 1, f);
00562     for (int i = 0; i < trailSize; i++) {
00563         Handle handle = trail->getElement(i);
00564         fwrite(&handle, sizeof(Handle), 1, f);
00565     }
00566 
00567 }
00568 
00569 void SavingLoading::writeAttentionValue(FILE *f, const AttentionValue& attentionValue)
00570 {
00571     AttentionValue::sti_t tempSTI = attentionValue.getSTI();
00572     AttentionValue::lti_t tempLTI = attentionValue.getLTI();
00573     AttentionValue::vlti_t tempVLTI = attentionValue.getVLTI();
00574 
00575     fwrite(&tempSTI, sizeof(AttentionValue::sti_t), 1, f);
00576     fwrite(&tempLTI, sizeof(AttentionValue::lti_t), 1, f);
00577     fwrite(&tempVLTI, sizeof(AttentionValue::vlti_t), 1, f);
00578 }
00579 
00580 void SavingLoading::writeTruthValue(FILE *f, const TruthValue& tv)
00581 {
00582     std::string tvStr = tv.toString();
00583     logger().info( "SavingLoading::writeTruthValue() tvStr = %s\n", tvStr.c_str());
00584     TruthValueType type = tv.getType();
00585     int length = tvStr.size();
00586 
00587     fwrite(&type, sizeof(TruthValueType), 1, f);
00588     fwrite(&length, sizeof(int), 1, f);
00589     fwrite(tvStr.c_str(), sizeof(char), length, f);
00590 }
00591 
00592 AttentionValue *SavingLoading::readAttentionValue(FILE *f)
00593 {
00594     AttentionValue::sti_t tempSTI;
00595     AttentionValue::lti_t tempLTI;
00596     AttentionValue::vlti_t tempVLTI;
00597 
00598     fread(&tempSTI, sizeof(AttentionValue::sti_t), 1, f);
00599     fread(&tempLTI, sizeof(AttentionValue::lti_t), 1, f);
00600     fread(&tempVLTI, sizeof(AttentionValue::vlti_t), 1, f);
00601 
00602     return(AttentionValue::factory(tempSTI, tempLTI, tempVLTI));
00603 }
00604 
00605 
00606 TruthValue *SavingLoading::readTruthValue(FILE *f)
00607 {
00608     //logger().fine("SavingLoading::readTruthValue()");
00609     TruthValueType type;
00610     int length;
00611 
00612     fread(&type, sizeof(TruthValueType), 1, f);
00613     fread(&length, sizeof(int), 1, f);
00614     //logger().fine("SavingLoading::readTruthValue() type = %d, length =  %d", type, length);
00615     char *tvStr = new char[length+1];
00616     fread(tvStr, sizeof(char), length, f);
00617     tvStr[length] = '\0';
00618 
00619     //logger().fine("SavingLoading::readTruthValue() tvStr = %s\n", tvStr);
00620     logger().info("SavingLoading::readTruthValue() tvStr = %s\n", tvStr);
00621     TruthValue* result = TruthValue::factory(type, tvStr);
00622     delete[] tvStr;
00623     return result;
00624 }
00625 
00626 void SavingLoading::readLink(FILE *f, Link *link, HandleMap<Atom *> *handles)
00627 {
00628     logger().fine("SavingLoading::readLink()");
00629     readAtom(f, handles, link);
00630 
00631     // the link's arity is read from the file
00632     Arity arity;
00633     fread(&arity, sizeof(Arity), 1, f);
00634 
00635     // the link's outgoing set is read from the file
00636     for (int i = 0; i < arity; i++) {
00637         Handle h;
00638         fread(&h, sizeof(Handle), 1, f);
00639         link->outgoing.push_back( TLB::getHandle( handles->get(h) ) );
00640     }
00641 
00642     // the trail
00643     Trail *trail = link->getTrail();
00644     int trailSize;
00645     fread(&trailSize, sizeof(int), 1, f);
00646     for (int i = 0; i < trailSize; i++) {
00647         Handle handle;
00648         fread(&handle, sizeof(Handle), 1, f);
00649         trail->insert( handle, false);
00650     }
00651 }
00652 
00653 void SavingLoading::printProgress(const char *s, int n)
00654 {
00655     static int old = -1;
00656 
00657     if (old != n) {
00658         old = n;
00659         logger().debug("Memory %s: %d%% done.\r", s, n);
00660     }
00661 }
00662 
00663 void SavingLoading::addSavableRepository(SavableRepository *repository) throw (RuntimeException)
00664 {
00665     const char* id = repository->getId();
00666 
00667     RepositoryHash::const_iterator it = repositories.find(id);
00668     if (it != repositories.end()) {
00669         throw RuntimeException(TRACE_INFO, "SavingLoading - Duplicated repository ids: '%s'.", id);
00670     }
00671 
00672     repositories[id] = repository;
00673 }
00674 
00675 void SavingLoading::saveRepositories(FILE *f)
00676 {
00677     logger().fine("SavingLoading::saveRepositories");
00678     unsigned int size = repositories.size();
00679     fwrite(&size, sizeof(unsigned int), 1, f);
00680 
00681     for (RepositoryHash::const_iterator it = repositories.begin(); it != repositories.end(); it++) {
00682         const std::string& repId = it->first;
00683         int idSize = repId.length() + 1;
00684         fwrite(&idSize, sizeof(int), 1, f);
00685         fwrite(repId.c_str(), sizeof(char), idSize, f);
00686 
00687         logger().debug("Saving repository: %s", repId.c_str());
00688         SavableRepository* rep = it->second;
00689         rep->saveRepository(f);
00690 
00691     }
00692 }
00693 
00694 void SavingLoading::loadRepositories(FILE *f, HandleMap<Atom *> *conv) throw (RuntimeException)
00695 {
00696     logger().fine("SavingLoading::loadRepositories");
00697     unsigned int size;
00698     fread(&size, sizeof(unsigned int), 1, f);
00699 
00700     if (size != repositories.size()) {
00701         logger().warn("Number of repositories in dump file (%d) is different from number of registered repositories (%d)", size, repositories.size());
00702         return;
00703     }
00704 
00705     for (unsigned int i = 0; i < size; i++) {
00706         int idSize;
00707         fread(&idSize, sizeof(int), 1, f);
00708 
00709         std::auto_ptr<char> id(new char[idSize]);
00710 
00711         fread(id.get(), sizeof(char), idSize, f);
00712 
00713         logger().debug("Loading repository: %s\n", id.get());
00714 
00715         RepositoryHash::const_iterator it = repositories.find((const char *)id.get());
00716 
00717         if (it == repositories.end()) {
00718             throw RuntimeException(TRACE_INFO,
00719                                    "SavingLoading - Unknown repository id: '%s'.", id.get());
00720         }
00721 
00722 
00723         it->second->loadRepository(f, conv);
00724     }
00725 
00726 }
00727 
00728 void SavingLoading::clearRepositories()
00729 {
00730     logger().fine("SavingLoading::clearRepositories");
00731     for (RepositoryHash::const_iterator it = repositories.begin();
00732             it != repositories.end(); it++) {
00733 
00734         it->second->clear();
00735     }
00736 }

Generated on Fri Dec 4 23:23:29 2009 for OpenCog Framework by  doxygen 1.5.6