ndnSIM中概率缓存的简单实现

实际上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>
TypeId
ContentStoreWithMypro<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##RegistrationVariable

namespace 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自带的实现,至于在某些文章中看到的更细的齐普夫参数,我还不知道在哪里设置,有待进一步研究。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值