PersistentStore.cc

00001 // Copyright 2008 Michael Marsh, University of Maryland.
00002 //
00003 // This file is part of pydtn.
00004 //
00005 // pydtn is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // pydtn is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // The views and conclusions contained in the software and documentation
00019 // are those of the authors and should not be interpreted as representing
00020 // official policies, either expressed or implied, of the University
00021 // of Maryland.
00022 //
00023 // pydtn extends and embeds the Python interpreter, which is
00024 // Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025 // and is released under the PSF License Agreement.
00026 //
00027 // RANLUX random number generation uses the Boost library,
00028 // Copyright 1994-2006 by various authors (details in individual files),
00029 // which is released under the Boost Software License, Version 1.0.
00030 
00031 #include "simlpy/interpreter_defs.h"
00032 #include "simlpy/interpreter_hooks.h"
00033 
00034 #include "PersistentStore.h"
00035 #include "WrapNode.h"
00036 #include "dtn/Bundle.h"
00037 #include "simlpy/Clock.h"
00038 
00039 #include <iostream>
00040 
00041 
00042 //===================
00043 // PersistentBundle
00044 //===================
00045 PersistentBundle::PersistentBundle( DTN::Bundle* b ) :
00046    m_bundle( b ),
00047    m_timeAdded( Clock::time() ),
00048    m_numTries( 0 )
00049 {
00050    if ( 0 != b )
00051    {
00052       m_originator = b->source();
00053       m_seqNum = b->seqNum();
00054    }
00055 }
00056 
00057 PersistentBundle::PersistentBundle( const DTN::ByteString& originator,
00058                                     uint32_t seqNum ) :
00059    m_bundle( 0 ),
00060    m_originator( originator ),
00061    m_seqNum( seqNum ),
00062    m_numTries( 0 )
00063 {
00064 }
00065 
00066 PersistentBundle::~PersistentBundle()
00067 {
00068 }
00069 
00070 DTN::Bundle*
00071 PersistentBundle::bundle() const
00072 {
00073    return m_bundle;
00074 }
00075 
00076 bool
00077 PersistentBundle::operator<( const PersistentBundle& b ) const
00078 {
00079    if ( m_originator < b.m_originator ) return true;
00080    if ( m_originator > b.m_originator ) return false;
00081 
00082    if ( m_seqNum < b.m_seqNum ) return true;
00083    if ( m_seqNum > b.m_seqNum ) return false;
00084 
00085    return false;
00086 }
00087 
00088 
00089 //==================
00090 // PersistentStore
00091 //==================
00092 
00093 PersistentStore::PersistentStore( WrapNode* owner ) :
00094    DTN::PersistentBundleStore( &(owner->node()) ),
00095    m_bytesUsed(0),
00096    m_wowner( owner )
00097 {
00098 }
00099 
00100 PersistentStore::~PersistentStore()
00101 {
00102 }
00103 
00104 DTN::BundlePointer
00105 PersistentStore::p_addBundle( DTN::Bundle* b )
00106 {
00107    if ( 0 == b ) return DTN::BundlePointer();
00108    std::pair< BundleList::iterator , bool > r = m_list.insert( b );
00109    if ( r.second )
00110    {
00111       m_bytesUsed += b->size();
00112       return DTN::BundlePointer( new PersistentStoreItr(*this,r.first) );
00113    }
00114    return DTN::BundlePointer();
00115 }
00116 
00117 void
00118 PersistentStore::p_deleteBundle( DTN::Bundle* b )
00119 {
00120    if ( 0 == b ) return;
00121    if ( 0 != m_list.erase( b ) )
00122    {
00123       m_bytesUsed -= b->size();
00124    }
00125 }
00126 
00127 DTN::BundlePointer
00128 PersistentStore::p_getPointer( const DTN::BundlePointer& p )
00129 {
00130    if ( p.isNull() )
00131    {
00132       if ( m_list.empty() )
00133       {
00134          return DTN::BundlePointer();
00135       }
00136       return DTN::BundlePointer(
00137          new PersistentStoreItr(*this,m_list.begin()) );
00138    }
00139    BundleList::iterator itr = m_list.lower_bound( p.repr()->bundle() );
00140    if ( m_list.end() != itr )
00141    {
00142       return DTN::BundlePointer( new PersistentStoreItr(*this,itr) );
00143    }
00144    return DTN::BundlePointer();
00145 }
00146 
00147 DTN::BundlePointer
00148 PersistentStore::p_getPointer( const DTN::ByteString& sender, uint32_t seqNum )
00149 {
00150    BundleList::iterator itr = m_list.find( PersistentBundle(sender,seqNum) );
00151    if ( m_list.end() == itr )
00152    {
00153       return DTN::BundlePointer();
00154    }
00155    return DTN::BundlePointer( new PersistentStoreItr(*this,itr) );
00156 }
00157 
00158 bool
00159 PersistentStore::p_validatePointer( const DTN::BundlePointer& p )
00160 {
00161    if ( p.isNull() ) return false;
00162    BundleList::iterator itr = m_list.find( p.repr()->bundle() );
00163    if ( m_list.end() == itr ) return false;
00164    return true;
00165 }
00166 
00167 void
00168 PersistentStore::p_shrinkStore( size_t s )
00169 {
00170    // This loop is not efficient.  If we wanted to be efficient, we'd
00171    // store a separate list of bundles sorted by time added.  However,
00172    // we don't expect this to be called often, so a little
00173    // inefficiency here does no real harm.  This is, after all, fairly
00174    // major node reconfiguration.
00175    while ( m_bytesUsed > s )
00176    {
00177       if ( 0 == m_list.size() ) return;
00178       BundleList::reverse_iterator itr = m_list.rbegin();
00179       BundleList::reverse_iterator end = m_list.rend();
00180       BundleList::reverse_iterator last = itr;
00181       for ( ; itr != end ; ++itr )
00182       {
00183          if ( itr->timeAdded() > last->timeAdded() )
00184          {
00185             last = itr;
00186          }
00187       }
00188       m_owner->recordPersistentRemove( *(last->bundle()) );
00189       p_deleteBundle(last->bundle());
00190       delete last->bundle();
00191    }
00192 }
00193 
00194 PersistentStore::BundleList::iterator
00195 PersistentStore::begin()
00196 {
00197    return m_list.begin();
00198 }
00199 
00200 PersistentStore::BundleList::iterator
00201 PersistentStore::lower_bound( const key_type& x )
00202 {
00203    return m_list.lower_bound( x );
00204 }
00205 
00206 PersistentStore::BundleList::iterator
00207 PersistentStore::upper_bound( const key_type& x )
00208 {
00209    return m_list.upper_bound( x );
00210 }
00211 
00212 PersistentStore::BundleList::iterator
00213 PersistentStore::end()
00214 {
00215    return m_list.end();
00216 }
00217 
00218 PersistentStore::BundleList::const_iterator
00219 PersistentStore::begin() const
00220 {
00221    return m_list.begin();
00222 }
00223 
00224 PersistentStore::BundleList::const_iterator
00225 PersistentStore::lower_bound( const key_type& x ) const
00226 {
00227    return m_list.lower_bound( x );
00228 }
00229 
00230 PersistentStore::BundleList::const_iterator
00231 PersistentStore::upper_bound( const key_type& x ) const
00232 {
00233    return m_list.upper_bound( x );
00234 }
00235 
00236 PersistentStore::BundleList::const_iterator
00237 PersistentStore::end() const
00238 {
00239    return m_list.end();
00240 }
00241 
00242 
00243 //=====================
00244 // PersistentStoreItr
00245 //=====================
00246 
00247 PersistentStoreItr::PersistentStoreItr(
00248    PersistentStore& store,
00249    PersistentStore::BundleList::iterator itr ) :
00250    DTN::BundlePointerRepr(),
00251    m_store( store ),
00252    m_itr( itr )
00253 {
00254 }
00255 
00256 PersistentStoreItr::~PersistentStoreItr()
00257 {
00258 }
00259 
00260 bool
00261 PersistentStoreItr::operator==( const DTN::BundlePointerRepr& b )
00262 {
00263    return false;
00264 }
00265 
00266 DTN::BundlePointerRepr*
00267 PersistentStoreItr::next()
00268 {
00269    PersistentStore::BundleList::iterator itr = m_store.upper_bound( *m_itr );
00270    if ( itr != m_store.end() )
00271    {
00272       return new PersistentStoreItr( m_store, itr );
00273    }
00274    return 0;
00275 }
00276 
00277 DTN::BundlePointerRepr*
00278 PersistentStoreItr::clone()
00279 {
00280    return new PersistentStoreItr( m_store, m_itr );
00281 }
00282 
00283 DTN::Bundle*
00284 PersistentStoreItr::bundle() const
00285 {
00286    return m_itr->bundle();
00287 }

Generated on Mon Mar 24 11:15:46 2008 for Pydtn Simulator by  doxygen 1.5.4