Back to index

lightning-sunbird  0.9+nobinonly
morkAtomSpace.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MDB_
00039 #include "mdb.h"
00040 #endif
00041 
00042 #ifndef _MORK_
00043 #include "mork.h"
00044 #endif
00045 
00046 #ifndef _MORKNODE_
00047 #include "morkNode.h"
00048 #endif
00049 
00050 #ifndef _MORKMAP_
00051 #include "morkMap.h"
00052 #endif
00053 
00054 #ifndef _MORKSPACE_
00055 #include "morkSpace.h"
00056 #endif
00057 
00058 #ifndef _MORKENV_
00059 #include "morkEnv.h"
00060 #endif
00061 
00062 #ifndef _MORKSPACE_
00063 #include "morkSpace.h"
00064 #endif
00065 
00066 #ifndef _MORKATOMSPACE_
00067 #include "morkAtomSpace.h"
00068 #endif
00069 
00070 #ifndef _MORKPOOL_
00071 #include "morkPool.h"
00072 #endif
00073 
00074 #ifndef _MORKSTORE_
00075 #include "morkStore.h"
00076 #endif
00077 
00078 #ifndef _MORKATOM_
00079 #include "morkAtom.h"
00080 #endif
00081 
00082 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00083 
00084 // ````` ````` ````` ````` ````` 
00085 // { ===== begin morkNode interface =====
00086 
00087 /*public virtual*/ void
00088 morkAtomSpace::CloseMorkNode(morkEnv* ev) // CloseAtomSpace() only if open
00089 {
00090   if ( this->IsOpenNode() )
00091   {
00092     this->MarkClosing();
00093     this->CloseAtomSpace(ev);
00094     this->MarkShut();
00095   }
00096 }
00097 
00098 /*public virtual*/
00099 morkAtomSpace::~morkAtomSpace() // assert CloseAtomSpace() executed earlier
00100 {
00101   MORK_ASSERT(mAtomSpace_HighUnderId==0);
00102   MORK_ASSERT(mAtomSpace_HighOverId==0);
00103   MORK_ASSERT(this->IsShutNode());
00104   MORK_ASSERT(mAtomSpace_AtomAids.IsShutNode());
00105   MORK_ASSERT(mAtomSpace_AtomBodies.IsShutNode());
00106 }
00107 
00108 /*public non-poly*/
00109 morkAtomSpace::morkAtomSpace(morkEnv* ev, const morkUsage& inUsage,
00110   mork_scope inScope, morkStore* ioStore,
00111   nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
00112 : morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
00113 , mAtomSpace_HighUnderId( morkAtomSpace_kMinUnderId )
00114 , mAtomSpace_HighOverId( morkAtomSpace_kMinOverId )
00115 , mAtomSpace_AtomAids(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
00116 , mAtomSpace_AtomBodies(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
00117 {
00118   // the morkSpace base constructor handles any dirty propagation
00119   if ( ev->Good() )
00120     mNode_Derived = morkDerived_kAtomSpace;
00121 }
00122 
00123 /*public non-poly*/ void
00124 morkAtomSpace::CloseAtomSpace(morkEnv* ev) // called by CloseMorkNode();
00125 {
00126   if ( this )
00127   {
00128     if ( this->IsNode() )
00129     {
00130       mAtomSpace_AtomBodies.CloseMorkNode(ev);
00131       morkStore* store = mSpace_Store;
00132       if ( store )
00133         this->CutAllAtoms(ev, &store->mStore_Pool);
00134       
00135       mAtomSpace_AtomAids.CloseMorkNode(ev);
00136       this->CloseSpace(ev);
00137       mAtomSpace_HighUnderId = 0;
00138       mAtomSpace_HighOverId = 0;
00139       this->MarkShut();
00140     }
00141     else
00142       this->NonNodeError(ev);
00143   }
00144   else
00145     ev->NilPointerError();
00146 }
00147 
00148 // } ===== end morkNode methods =====
00149 // ````` ````` ````` ````` ````` 
00150 
00151 /*static*/ void
00152 morkAtomSpace::NonAtomSpaceTypeError(morkEnv* ev)
00153 {
00154   ev->NewError("non morkAtomSpace");
00155 }
00156 
00157 mork_num
00158 morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool)
00159 {
00160 #ifdef MORK_ENABLE_ZONE_ARENAS
00161   MORK_USED_2(ev, ioPool);
00162   return 0;
00163 #else /*MORK_ENABLE_ZONE_ARENAS*/
00164   if ( this->IsAtomSpaceClean() )
00165     this->MaybeDirtyStoreAndSpace();
00166   
00167   mork_num outSlots = mAtomSpace_AtomAids.MapFill();
00168   morkBookAtom* a = 0; // old key atom in the map
00169   
00170   morkStore* store = mSpace_Store;
00171   mork_change* c = 0;
00172   morkAtomAidMapIter i(ev, &mAtomSpace_AtomAids);
00173   for ( c = i.FirstAtom(ev, &a); c ; c = i.NextAtom(ev, &a) )
00174   {
00175     if ( a )
00176       ioPool->ZapAtom(ev, a, &store->mStore_Zone);
00177 
00178 #ifdef MORK_ENABLE_PROBE_MAPS
00179     // do not cut anything from the map
00180 #else /*MORK_ENABLE_PROBE_MAPS*/
00181     i.CutHereAtom(ev, /*key*/ (morkBookAtom**) 0);
00182 #endif /*MORK_ENABLE_PROBE_MAPS*/
00183   }
00184   
00185   return outSlots;
00186 #endif /*MORK_ENABLE_ZONE_ARENAS*/
00187 }
00188 
00189 
00190 morkBookAtom*
00191 morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
00192    const morkFarBookAtom& inAtom,  mork_aid inAid)
00193 // Make copy of inAtom and put it in both maps, using specified ID.
00194 {
00195   morkBookAtom* outAtom = 0;
00196   morkStore* store = mSpace_Store;
00197   if ( ev->Good() && store )
00198   {
00199     morkPool* pool = this->GetSpaceStorePool();
00200     outAtom = pool->NewFarBookAtomCopy(ev, inAtom, &store->mStore_Zone);
00201     if ( outAtom )
00202     {
00203       if ( store->mStore_CanDirty )
00204       {
00205         outAtom->SetAtomDirty();
00206         if ( this->IsAtomSpaceClean() )
00207           this->MaybeDirtyStoreAndSpace();
00208       }
00209   
00210       outAtom->mBookAtom_Id = inAid;
00211       outAtom->mBookAtom_Space = this;
00212       mAtomSpace_AtomAids.AddAtom(ev, outAtom);
00213       mAtomSpace_AtomBodies.AddAtom(ev, outAtom);
00214       if ( this->SpaceScope() == morkAtomSpace_kColumnScope )
00215         outAtom->MakeCellUseForever(ev);
00216 
00217       if ( mAtomSpace_HighUnderId <= inAid )
00218         mAtomSpace_HighUnderId = inAid + 1;
00219     }
00220   }
00221   return outAtom;
00222 }
00223 
00224 morkBookAtom*
00225 morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom)
00226 // make copy of inAtom and put it in both maps, using a new ID as needed.
00227 {
00228   morkBookAtom* outAtom = 0;
00229   morkStore* store = mSpace_Store;
00230   if ( ev->Good() && store )
00231   {
00232     if ( store->mStore_CanAutoAssignAtomIdentity )
00233     {
00234       morkPool* pool = this->GetSpaceStorePool();
00235       morkBookAtom* atom = pool->NewFarBookAtomCopy(ev, inAtom, &mSpace_Store->mStore_Zone);
00236       if ( atom )
00237       {
00238         mork_aid id = this->MakeNewAtomId(ev, atom);
00239         if ( id )
00240         {
00241           if ( store->mStore_CanDirty )
00242           {
00243             atom->SetAtomDirty();
00244             if ( this->IsAtomSpaceClean() )
00245               this->MaybeDirtyStoreAndSpace();
00246           }
00247             
00248           outAtom = atom; 
00249           atom->mBookAtom_Space = this;
00250           mAtomSpace_AtomAids.AddAtom(ev, atom);
00251           mAtomSpace_AtomBodies.AddAtom(ev, atom);
00252           if ( this->SpaceScope() == morkAtomSpace_kColumnScope )
00253             outAtom->MakeCellUseForever(ev);
00254         }
00255         else
00256           pool->ZapAtom(ev, atom, &mSpace_Store->mStore_Zone);
00257       }
00258     }
00259     else
00260       mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
00261   }
00262   return outAtom;
00263 }
00264 
00265 
00266 mork_aid
00267 morkAtomSpace::MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom)
00268 {
00269   mork_aid outAid = 0;
00270   mork_tid id = mAtomSpace_HighUnderId;
00271   mork_num count = 8; // try up to eight times
00272   
00273   while ( !outAid && count ) // still trying to find an unused table ID?
00274   {
00275     --count;
00276     ioAtom->mBookAtom_Id = id;
00277     if ( !mAtomSpace_AtomAids.GetAtom(ev, ioAtom) )
00278       outAid = id;
00279     else
00280     {
00281       MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems
00282       ++id;
00283     }
00284   }
00285   
00286   mAtomSpace_HighUnderId = id + 1;
00287   return outAid;
00288 }
00289 
00290 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00291 
00292 
00293 morkAtomSpaceMap::~morkAtomSpaceMap()
00294 {
00295 }
00296 
00297 morkAtomSpaceMap::morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage,
00298   nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
00299   : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap)
00300 {
00301   if ( ev->Good() )
00302     mNode_Derived = morkDerived_kAtomSpaceMap;
00303 }
00304 
00305 
00306 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00307