ndnSIM中概率缓存的简单实现

来源:互联网 发布:马库斯斯玛特体测数据 编辑:程序博客网 时间:2024/05/15 01:08

实际上ndnSIM2.1中已经自带概率缓存的实现了,在自己的配置文件中,加入

ndn::StackHelper ndnHelper;ndnHelper.SetOldContentStore("ns3::ndn::cs::Probability::Lru","MaxSize","100","CacheProbability","0.5");

就可以设置好一个最大缓存为100,缓存概率为0.5的缓存。

这里记录它是如何实现的,并以另一种方法实现概率缓存。

方法一:利用配置文件直接配置缓存策略

这种方法就是上面所说的方法,在配置文件中调用SetOldContentStore()函数。这里我们要做的是去了解这些策略文件的位置,以及我们怎么去写简单的策略。

ns-3/src/ndnSIM/model/cs

中,存放着有关ndnSIM缓存策略的文件。ndnSIM2.1自带四种策略:
1. freshness
2. stats
3. probability
4. nocache

每种策略都有三个文件,拿probability为例,有

  • content-store-with-probability.hpp
  • content-store-with-probability.cpp
  • custom-policies/probability-policy.hpp

如果要写自己的缓存策略,只要仿照这三个文件,再写三个文件,然后在配置文件中调用即可。

这里放上一个简单的MyPro实现,仅仅是将probability的名称改了。

//content-store-with-mypro.hpp#ifndef NDN_CONTENT_STORE_WITH_MYPRO_H_#define NDN_CONTENT_STORE_WITH_MYPRO_H_#include "ns3/ndnSIM/model/ndn-common.hpp"#include "content-store-impl.hpp"#include "../../utils/trie/multi-policy.hpp"#include "custom-policies/mypro-policy.hpp"#include "ns3/double.h"#include "ns3/type-id.h"namespace ns3 {namespace ndn {namespace cs {/** * @ingroup ndn-cs * @brief Special content store realization that probabilistically accepts data packet *        into CS (placement policy) */template<class Policy>class ContentStoreWithMypro  : public ContentStoreImpl<ndnSIM::multi_policy_traits<boost::mpl::                                                          vector2<ndnSIM::mypro_policy_traits,                                                                  Policy>>> {public:  typedef ContentStoreImpl<ndnSIM::multi_policy_traits<boost::mpl::                                                         vector2<ndnSIM::mypro_policy_traits,                                                                 Policy>>> super;  typedef typename super::policy_container::template index<0>::type mypro_policy_container;  ContentStoreWithMypro(){};  static TypeId  GetTypeId();private:  void  SetCacheProbability(double probability)  {    this->getPolicy().template get<mypro_policy_container>().set_probability(probability);    printf("SetCacheProbability:%lf\n", probability);  }  double  GetCacheProbability() const  {    printf("GetCacheProbability:%lf\n", this->getPolicy().template get<mypro_policy_container>().get_probability());    return this->getPolicy().template get<mypro_policy_container>().get_probability();  }};//////////////////////////////////////////////////// Implementation //////////////////////////////////////////////////////////template<class Policy>TypeIdContentStoreWithMypro<Policy>::GetTypeId(){  static TypeId tid =    TypeId(("ns3::ndn::cs::Mypro::" + Policy::GetName()).c_str())      .SetGroupName("Ndn")      .SetParent<super>()      .template AddConstructor<ContentStoreWithMypro<Policy>>()      .AddAttribute("CacheProbability",                    "Set probability of caching in ContentStore. "                    "If 1, every content is cached. If 0, no content is cached.",                    DoubleValue(1.0), //(+)                    MakeDoubleAccessor(&ContentStoreWithMypro<Policy>::GetCacheProbability,                                       &ContentStoreWithMypro<Policy>::SetCacheProbability),                    MakeDoubleChecker<double>());      printf("typename:ns3::ndn::cs::Mypro::%s\n",Policy::GetName().c_str());  return tid;}} // namespace cs} // namespace ndn} // namespace ns3#endif // NDN_CONTENT_STORE_WITH_PROBABILITY_H_
//content-store-with-mypro.cpp#include "content-store-with-mypro.hpp"#include "../../utils/trie/random-policy.hpp"#include "../../utils/trie/lru-policy.hpp"#include "../../utils/trie/fifo-policy.hpp"#include "../../utils/trie/lfu-policy.hpp"#define NS_OBJECT_ENSURE_REGISTERED_TEMPL(type, templ)                                             \  static struct X##type##templ##RegistrationClass {                                                \    X##type##templ##RegistrationClass()                                                            \    {                                                                                              \      ns3::TypeId tid = type<templ>::GetTypeId();                                                  \      tid.GetParent();                                                                             \    }                                                                                              \  } x_##type##templ##RegistrationVariablenamespace ns3 {namespace ndn {using namespace ndnSIM;namespace cs {// explicit instantiation and registering/** * @brief ContentStore with freshness and LRU cache replacement policy **/template class ContentStoreWithMypro<lru_policy_traits>;/** * @brief ContentStore with freshness and random cache replacement policy **/template class ContentStoreWithMypro<random_policy_traits>;/** * @brief ContentStore with freshness and FIFO cache replacement policy **/template class ContentStoreWithMypro<fifo_policy_traits>;/** * @brief ContentStore with freshness and Least Frequently Used (LFU) cache replacement policy **/template class ContentStoreWithMypro<lfu_policy_traits>;NS_OBJECT_ENSURE_REGISTERED_TEMPL(ContentStoreWithMypro, lru_policy_traits);NS_OBJECT_ENSURE_REGISTERED_TEMPL(ContentStoreWithMypro, random_policy_traits);NS_OBJECT_ENSURE_REGISTERED_TEMPL(ContentStoreWithMypro, fifo_policy_traits);NS_OBJECT_ENSURE_REGISTERED_TEMPL(ContentStoreWithMypro, lfu_policy_traits);#ifdef DOXYGEN// /**//  * \brief Content Store with freshness implementing LRU cache replacement policy//  */class Mypro::Lru : public ContentStoreWithMypro<lru_policy_traits> {};/** * \brief Content Store with freshness implementing FIFO cache replacement policy */class Mypro::Fifo : public ContentStoreWithMypro<fifo_policy_traits> {};/** * \brief Content Store with freshness implementing Random cache replacement policy */class Mypro::Random : public ContentStoreWithMypro<random_policy_traits> {};/** * \brief Content Store with freshness implementing Least Frequently Used cache replacement policy */class Mypro::Lfu : public ContentStoreWithMypro<lfu_policy_traits> {};#endif} // namespace cs} // namespace ndn} // namespace ns3
custom-policies/mypro-policy.hpp#ifndef MYPRO_POLICY_H_#define MYPRO_POLICY_H_/// @cond include_hidden#include "ns3/ndnSIM/model/ndn-common.hpp"#include <boost/intrusive/options.hpp>#include <boost/intrusive/list.hpp>#include <ns3/random-variable-stream.h>namespace ns3 {namespace ndn {namespace ndnSIM {/** * @brief Traits for freshness policy */struct mypro_policy_traits {  static std::string  GetName()  {    return "MyproImpl";  }  struct policy_hook_type : public boost::intrusive::list_member_hook<> {  };  template<class Container>  struct container_hook {    typedef boost::intrusive::member_hook<Container, policy_hook_type, &Container::policy_hook_>      type;  };  template<class Base, class Container, class Hook>  struct policy {    typedef typename boost::intrusive::list<Container, Hook> policy_container;    class type : public policy_container {    public:      typedef policy policy_base; // to get access to get_freshness methods from outside      typedef Container parent_trie;      type(Base& base)        : base_(base)        , max_size_(100)        , probability_(1.0)        , ns3_rand_(CreateObject<UniformRandomVariable>())      {      }      inline void      update(typename parent_trie::iterator item)      {      }      inline bool      insert(typename parent_trie::iterator item)      {        if (ns3_rand_->GetValue() < probability_) {          policy_container::push_back(*item);          // allow caching          return true;        }        else {          // don't allow caching          return false;        }      }      inline void      lookup(typename parent_trie::iterator item)      {        // do nothing. it's random policy      }      inline void      erase(typename parent_trie::iterator item)      {        policy_container::erase(policy_container::s_iterator_to(*item));      }      inline void      clear()      {        policy_container::clear();      }      inline void      set_max_size(size_t max_size)      {        max_size_ = max_size;      }      inline size_t      get_max_size() const      {        return max_size_;      }      inline void      set_probability(double probability)      {        probability_ = probability;      }      inline double      get_probability() const      {        return probability_;      }    private:      type()        : base_(*((Base*)0)){};    private:      Base& base_;      size_t max_size_;      double probability_;      Ptr<UniformRandomVariable> ns3_rand_;    };  };};} // ndnSIM} // ndn} // ns3/// @endcond#endif // PROBABILITY_POLICY_H

可以看到custom-policies/mypro-policy.hpp中的insert函数实现了概率缓存的主要功能。
content-store-with-mypro.hpp中的GetTypeId中,AddAttribute是将自己的变量加入到配置中,这样就可以在配置文件中配置这些变量的值了。

在配置文件中的使用:

ndn::StackHelper ndnHelper;ndnHelper.SetOldContentStore("ns3::ndn::cs::Mypro::Lru","MaxSize","50","CacheProbability","0.5");

方法二:修改底层策略

ns-3/src/ndnSIM/NFD/daemon/fw中,存放着ndnSIM转发策略的一些文件。我们要修改的是forwarder.cpp

forwarder.cpp中,找到onIncomingData函数,其中有这么一段:

// CS insert  if (m_csFromNdnSim == nullptr)    m_cs.insert(*dataCopyWithoutPacket);  else    m_csFromNdnSim->Add(dataCopyWithoutPacket);

这就是默认的LCE策略,这里的两个变量m_csm_csFromNdnSim分别是ns-3/src/ndnSIM/NFD/daemon/table中的csns-3/src/ndnSIM/model/cs/ndn-content-store的对象,前者是ndnSIM2.0及以后对cs的实现,后者是1.0对cs的实现,这里代码中的CS insert对m_csFromNdnSim进行了一次判断,主要是看用户用的是哪一个版本的cs实现,然后在用各自的API将数据插入cs中。

在这里实现简单的概率缓存,只要生成一个随机数,然后与预设的阈值进行比较,如果小于阈值就缓存,否则什么都不做。代码如下:

// CS insert  srand(std::time(NULL));  float p = (float)rand()/RAND_MAX;//产生随机数  float propability = 0.5;//阈值的设定  //概率缓存  if(p < propability){    if (m_csFromNdnSim == nullptr)      m_cs.insert(*dataCopyWithoutPacket);    else      m_csFromNdnSim->Add(dataCopyWithoutPacket);  }  else{  }

这种方法就实现了简单的概率缓存,使用时不需要在配置文件中特地的进行策略的修改。

另外,在配置文件中,ndnSIM官网的例子给出的consumer实现都是

ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");

这种方式产生的Interest很难重复,就更不要说缓存命中了。因此我们要将Interest改为齐普夫分布。在配置文件中将上面的代码改为:

ndn::AppHelper consumerHelper("ns3::ndn::ConsumerZipfMandelbrot");

这是ndnSIM自带的实现,至于在某些文章中看到的更细的齐普夫参数,我还不知道在哪里设置,有待进一步研究。

0 0
原创粉丝点击