工具类分析-rak::partial_queue

说明:通过ChunkStatistics统计出所有chunk的供应数后,下一步就是要针对peer将其拥有的chunk按照稀缺度分layer,形象一点就是将chunk按照贵重程度放到7(num_layers)层玲珑宝塔(m_layers)中,不过这个宝塔有点特别,越往下越贵重。(重的东西是应该放下面)。每层的区间范围分别为 第0层到第7层

[0,1) [1,3) [3,7) [7,15) [15,31) [31,63) [63,127) [127,255)

注意:
1. 每层(layer)的数目有限m_maxLayerSize,seeder 32个,leecher 8个,但是在同一层中的chunk可能大于m_maxLayerSize,这称为overflowing,算法的处理是不弹出上一层的chunk,而是返回false,参考prepare_pop函数
2. 第0层(最底层)含义:chunk统计数为0的(只有seeder才可能插入)

成员变量:

  mapped_type*        m_data;        //按层排列的chunk index列表
  size_type           m_maxLayerSize;//每层的最大个数
  size_type           m_index;       //当前拥有成员的最底层,从第0层开始
  size_type           m_ceiling;     //可插入层的最大统计值,从最高层的最大值开始
  size_pair_type      m_layers[num_layers];//first 本层已经pop的chunk数,second 本层总共的chunk数
核心函数:
//构造,ls: 每层最大允许的chunk index数
inline void partial_queue::enable(size_type ls) {
  if (ls == 0)
    throw std::logic_error("partial_queue::enable(...) ls == 0.");

  delete [] m_data;
  m_data = new mapped_type[ls * num_layers];

  m_maxLayerSize = ls;
}
//销毁
inline void partial_queue::disable() {
  delete [] m_data;
  m_data = NULL;

  m_maxLayerSize = 0;
}
//清空
inline void partial_queue::clear() {
  if (m_data == NULL)
    return;

  m_index = 0;
  m_ceiling = ceiling(num_layers - 1);

  std::memset(m_layers, 0, num_layers * sizeof(size_pair_type));
}

/************************************************************************
增加一个成员
参数:            key:   成员身价,chunk的统计数,值越少越值钱  
                   value: 成员ID号,chunk index
说明:
    本算法按照chunk统计数,将chunk放到不同的层,如果中间某一层满了,继续往低一层放,直到使最低层满了,则整个queue满了(只有seeder可能做到),插入后m_index指向有chunk的最低层,m_ceiling表示可插入的层最高统计值
    本函数由ChunkSelector调用
************************************************************************/
inline bool partial_queue::insert(key_type key, mapped_type value) {
  if(key>= m_ceiling)
    return false;

  size_type idx= 0; 

  //找到layer
 
while(key>= ceiling(idx))
    ++idx;

  m_index= std::min(m_index, idx);

  // Currently don't allow overflow.
 
if(is_layer_full(idx))
    throwstd::logic_error("partial_queue::insert(...) layer already full."); 
    //记录chunk index
 
m_data[m_maxLayerSize* idx+ m_layers[idx].second] = value;
  m_layers[idx].second++;

  if(is_layer_full(idx))
    // 如果是第0层满了,则表示整个queue满了,否则到低一层
  
m_ceiling= idx> 0 ? ceiling(idx- 1) : 0;

  return true;
}

//定位到有un-popped chunk的最低层 
inline bool partial_queue::prepare_pop() {
  while (m_layers[m_index].first == m_layers[m_index].second) {
        //is_layer_full(m_index)表示overflowed,表示在当前layer的chunk大于m_maxLayerSize
    if (is_layer_full(m_index) || m_index + 1 == num_layers)
      return false;

    m_index++;
  }

  return true;
}
//获得chunk index
inline partial_queue::mapped_type partial_queue::pop() {
  if (m_index >= num_layers || m_layers[m_index].first >= m_layers[m_index].second)
    throw std::logic_error("partial_queue::pop() bad state.");

  return m_data[m_index * m_maxLayerSize + m_layers[m_index].first++];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值