Implementing content store using Boost.MultiIndex container
Adding .SetGroupName("Ccnx") call to Ccnx-related objects (probably
missed some). This call is advisory, but it is nice to give users
information about Ccnx-related objects (this information is accessible
via --PrintGroup=Ccnx command line argument)
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 31a9fb3..4633000 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -16,88 +16,135 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "ccnx-content-store.h"
#include "ns3/log.h"
-
+#include "ns3/packet.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/uinteger.h"
NS_LOG_COMPONENT_DEFINE ("CcnxContentStore");
namespace ns3
{
-
-CcnxContentStore::CcnxContentStore( int maxSize )
- : m_maxSize(maxSize) { }
+
+NS_OBJECT_ENSURE_REGISTERED (CcnxContentStore);
+
+using namespace __ccnx_private;
+
+TypeId
+CcnxContentStore::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::CcnxContentStore")
+ .SetGroupName ("Ccnx")
+ .SetParent<Object> ()
+ .AddConstructor<CcnxContentStore> ()
+ .AddAttribute ("Size",
+ "Maximum number of packets that content storage can hold",
+ UintegerValue (100),
+ MakeUintegerAccessor (&CcnxContentStore::SetMaxSize,
+ &CcnxContentStore::GetMaxSize),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+
+ return tid;
+}
+
+CcnxContentObjectTail CcnxContentStoreEntry::m_tail;
+
+CcnxContentStoreEntry::CcnxContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
+ : m_header (header)
+{
+ m_packet = packet->Copy ();
+ m_packet->RemoveHeader (*header);
+ m_packet->RemoveTrailer (m_tail);
+}
+
+Ptr<Packet>
+CcnxContentStoreEntry::GetFullyFormedCcnxPacket () const
+{
+ Ptr<Packet> packet = m_packet->Copy ();
+ packet->AddHeader (*m_header);
+ packet->AddTrailer (m_tail);
+ return packet;
+}
+
+// /// Disabled copy constructor
+// CcnxContentStoreEntry::CcnxContentStoreEntry (const CcnxContentStoreEntry &o)
+// {
+// }
+
+// /// Disables copy operator
+// CcnxContentStoreEntry& CcnxContentStoreEntry::operator= (const CcnxContentStoreEntry &o)
+// {
+// return *this;
+// }
+
+
+
+CcnxContentStore::CcnxContentStore( )
+ : m_maxSize(100) { } // this value shouldn't matter, NS-3 should call SetSize with default value specified in AddAttribute earlier
CcnxContentStore::~CcnxContentStore( )
- { }
+{ }
-//Find corresponding CS entry for the given content name
-CsEntry*
-CcnxContentStore::Lookup(const string prefix )
+/// Disabled copy constructor
+CcnxContentStore::CcnxContentStore (const CcnxContentStore &o)
{
- CriticalSection section(m_csMutex);
-
- CsEntry *result = &(m_contentStore.at(prefix));
-
- if(result != NULL)
- Promote (*result);
-
- return result;
+}
+
+/// Disables copy operator
+CcnxContentStore& CcnxContentStore::operator= (const CcnxContentStore &o)
+{
+ return *this;
+}
+
+
+Ptr<Packet>
+CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
+{
+ CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (interest->GetName ());
+ if (it != m_contentStore.end ())
+ {
+ // promote entry to the top
+ m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+ m_contentStore.project<mru> (it));
+
+ // return fully formed CCNx packet
+ return it->GetFullyFormedCcnxPacket ();
+ }
+ return 0;
}
-//move the given CS entry to the head of the list
void
-CcnxContentStore::Promote(CsEntry &ce )
+CcnxContentStore::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
{
- // should not lock mutex. Otherwise deadlocks will be welcome
- if( m_LRU.front() == &ce ) return;
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-
- // swaping positions in _lru
- m_LRU.erase( ce.lruPosition );
- m_LRU.push_front( &ce );
- ce.lruPosition = m_LRU.begin( );
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-//Add entry to content store, if content store is full, use LRU replacement
-void
-CcnxContentStore::Add( const string contentName, int contentSize )
-{
- CriticalSection section(m_csMutex);
-
- m_contentStore.erase(m_contentStore.find(contentName));
-
- if((int)m_contentStore.size() == m_maxSize )
- {
- CsEntry *entry = m_LRU.back();
- m_contentStore.erase(m_contentStore.find(entry->contentName));
- m_LRU.pop_back( );
+ CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (header->GetName ());
+ if (it == m_contentStore.end ())
+ { // add entry to the top
+ m_contentStore.get<mru> ().push_front (CcnxContentStoreEntry (header, packet));
}
-
- CsEntry ce;
- ce.contentName = contentName;
- ce.contentSize = contentSize;
-
- m_contentStore[contentName] = ce;
-
- CsEntry *ce_in_hash = &(m_contentStore.at(contentName));
- m_LRU.push_front( ce_in_hash );
- ce_in_hash->lruPosition = m_LRU.begin( );
-}
-
-void
-CcnxContentStore::Dump()
-{
- CriticalSection section(m_csMutex);
-
- BOOST_FOREACH(string_key_hash_t<CsEntry>::value_type i, m_contentStore)
+ else
{
- NS_LOG_INFO ("Key = " << i.first << " Value = " << i.second.contentName);
+ // promote entry to the top
+ m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+ m_contentStore.project<mru> (it));
}
}
-}
\ No newline at end of file
+
+void
+CcnxContentStore::Print() const
+{
+ for( DUMP_INDEX::type::iterator it=m_contentStore.get<DUMP_INDEX_TAG> ().begin ();
+ it != m_contentStore.get<DUMP_INDEX_TAG> ().end ();
+ it++
+ )
+ {
+ NS_LOG_INFO (it->GetName ());
+ }
+}
+
+} // namespace ns3