FlatStore.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 "FlatStore.h"
00032 #include "dtn/Bundle.h"
00033 #include "dtn/Node.h"
00034 #include "dtn/DropCause.h"
00035 #include "simlpy/Time.h"
00036 
00037 #include <iostream>
00038 
00039 //============
00040 // FlatStore
00041 //============
00042 
00043 FlatStore::FlatStore( DTN::Node* owner ) :
00044    DTN::VolatileBundleStore( owner ),
00045    m_bytesUsed(0)
00046 {
00047 }
00048 
00049 FlatStore::~FlatStore()
00050 {
00051    BundleList::iterator itr = m_list.begin();
00052    BundleList::iterator end = m_list.end();
00053    for ( ; itr != end ; ++itr )
00054    {
00055       if ( 0 != *itr ) delete *itr;
00056    }
00057 }
00058 
00059 DTN::BundlePointer
00060 FlatStore::p_addBundle( DTN::Bundle* b )
00061 {
00062    if ( 0 == b ) return DTN::BundlePointer();
00063    std::pair< BundleList::iterator , bool > r = m_list.insert( b );
00064    if ( r.second )
00065    {
00066       m_bytesUsed += b->size();
00067       return DTN::BundlePointer( new FlatStoreItr(*this,r.first) );
00068    }
00069    return DTN::BundlePointer();
00070 }
00071 
00072 void
00073 FlatStore::p_deleteBundle( DTN::Bundle* b )
00074 {
00075    if ( 0 == b ) return;
00076    if ( 0 != m_list.erase( b ) )
00077    {
00078       m_bytesUsed -= b->size();
00079    }
00080 }
00081 
00082 DTN::BundlePointer
00083 FlatStore::p_getPointer( const DTN::BundlePointer& p )
00084 {
00085    if ( p.isNull() )
00086    {
00087       if ( m_list.empty() )
00088       {
00089          return DTN::BundlePointer();
00090       }
00091       return DTN::BundlePointer( new FlatStoreItr(*this,m_list.begin()) );
00092    }
00093    BundleList::iterator itr = m_list.lower_bound( p.repr()->bundle() );
00094    if ( m_list.end() == itr )
00095    {
00096       return DTN::BundlePointer();
00097    }
00098    return DTN::BundlePointer( new FlatStoreItr(*this,itr) );
00099 }
00100 
00101 DTN::BundlePointer
00102 FlatStore::p_getPointer( const DTN::ByteString& sender, uint32_t seqNum )
00103 {
00104    // Since we're just storing a set, sorted on memory address, we have
00105    // to do a slow iteration through the list.  This isn't a big deal,
00106    // as this method isn't likely to get called very often for this
00107    // type of BundleStore.
00108    BundleList::iterator itr = m_list.begin();
00109    BundleList::iterator end = m_list.end();
00110    for ( ; itr != end ; ++itr )
00111    {
00112       if ( 0 != *itr )
00113       {
00114          if ( ( (*itr)->source() == sender ) &&
00115               ( (*itr)->seqNum() == seqNum ) )
00116          {
00117             return DTN::BundlePointer( new FlatStoreItr(*this,itr) );
00118          }
00119       }
00120    }
00121    return DTN::BundlePointer();
00122 }
00123 
00124 bool
00125 FlatStore::p_validatePointer( const DTN::BundlePointer& p )
00126 {
00127    if ( p.isNull() ) return false;
00128    return ( m_list.end() != m_list.find( p.repr()->bundle() ) );
00129 }
00130 
00131 void
00132 FlatStore::p_shrinkStore( size_t s )
00133 {
00134    while ( m_bytesUsed > s )
00135    {
00136       if ( 0 == m_list.size() ) return;
00137       BundleList::reverse_iterator itr = m_list.rbegin();
00138       BundleList::reverse_iterator end = m_list.rend();
00139       BundleList::reverse_iterator last = itr;
00140       if ( 0 == *last ) return;
00141       Time tLast( (*last)->created() );
00142       for ( ; itr != end ; ++itr )
00143       {
00144          if ( 0 != *itr )
00145          {
00146             Time tItr( (*itr)->created() );
00147             if ( tItr > tLast )
00148             {
00149                last = itr;
00150             }
00151          }
00152       }
00153       p_deleteBundle(*last);
00154       m_owner->drop( *last, DTN::ExpiryDrop::inst );
00155    }
00156 }
00157 
00158 FlatStore::BundleList::iterator
00159 FlatStore::begin()
00160 {
00161    return m_list.begin();
00162 }
00163 
00164 FlatStore::BundleList::iterator
00165 FlatStore::lower_bound( const key_type& x )
00166 {
00167    return m_list.lower_bound( x );
00168 }
00169 
00170 FlatStore::BundleList::iterator
00171 FlatStore::upper_bound( const key_type& x )
00172 {
00173    return m_list.upper_bound( x );
00174 }
00175 
00176 FlatStore::BundleList::iterator
00177 FlatStore::end()
00178 {
00179    return m_list.end();
00180 }
00181 
00182 FlatStore::BundleList::const_iterator
00183 FlatStore::begin() const
00184 {
00185    return m_list.begin();
00186 }
00187 
00188 FlatStore::BundleList::const_iterator
00189 FlatStore::lower_bound( const key_type& x ) const
00190 {
00191    return m_list.lower_bound( x );
00192 }
00193 
00194 FlatStore::BundleList::const_iterator
00195 FlatStore::upper_bound( const key_type& x ) const
00196 {
00197    return m_list.upper_bound( x );
00198 }
00199 
00200 FlatStore::BundleList::const_iterator
00201 FlatStore::end() const
00202 {
00203    return m_list.end();
00204 }
00205 
00206 
00207 //===============
00208 // FlatStoreItr
00209 //===============
00210 
00211 FlatStoreItr::FlatStoreItr( FlatStore& store,
00212                             FlatStore::BundleList::iterator itr ) :
00213    DTN::BundlePointerRepr(),
00214    m_store( store ),
00215    m_itr( itr )
00216 {
00217 }
00218 
00219 FlatStoreItr::~FlatStoreItr()
00220 {
00221 }
00222 
00223 bool
00224 FlatStoreItr::operator==( const DTN::BundlePointerRepr& b )
00225 {
00226    return b.bundle() == *m_itr;
00227 }
00228 
00229 DTN::BundlePointerRepr*
00230 FlatStoreItr::next()
00231 {
00232    FlatStore::BundleList::iterator itr = m_store.upper_bound( *m_itr );
00233    if ( itr == m_store.end() )
00234    {
00235       return 0;
00236    }
00237    return new FlatStoreItr( m_store, itr );
00238 }
00239 
00240 DTN::BundlePointerRepr*
00241 FlatStoreItr::clone()
00242 {
00243    return new FlatStoreItr( m_store, m_itr );
00244 }
00245 
00246 DTN::Bundle*
00247 FlatStoreItr::bundle() const
00248 {
00249    return *m_itr;
00250 }

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