打开微信,使用扫一扫进入页面后,点击右上角菜单,
点击“发送给朋友”或“分享到朋友圈”完成分享
基于samples/example/example.cpp代码
我们创建一个pipeline流水线后里面维持着一些Module和stream,如何保存他们之间的独立性,这里利用到了Pipeline类里面的一个私有成员(测试时公有)IdxManager类指针,它指向一个IdxManager类。
下面展开IdxManager类,它是一个在pipeline里面创建、管理、销毁Moudle和stream的idx的类,也就是说它能保证idx的唯一性:
class IdxManager {
public:
IdxManager() = default;
IdxManager(const IdxManager&) = delete;
IdxManager& operator=(const IdxManager&) = delete;
uint32_t GetStreamIndex(const std::string& stream_id);
// 本质的实现是从0到Max查找,如果没有在stream_bitset里面的就可以分配为index。
void ReturnStreamIndex(const std::string& stream_id);
// 这里返回的查找对应stream_bitset和stream_idx_map会将查找的复原,这个位置又空出来
size_t GetModuleIdx();
// module的index使用的是掩码的方法
void ReturnModuleIdx(size_t id_);
// module_id_mask_ &= ~(1 << id_);把当前为变0
private:
SpinLock id_lock;
std::unordered_map<std::string, uint32_t> stream_idx_map;
std::bitset<MAX_STREAM_NUM> stream_bitset;
// 所有分配stream的index都在这里
uint64_t module_id_mask_ = 0;
// 所有分配的module的index都在这,根据这个方法,module最大支持64个
}; // class IdxManager1、stream分配idx的方法:
利用一个bitset来存储可以节省空间,每个元素占1bit,每个元素存储0或者1。我们通过bitset的索引找到元素值,如我们找bitset的第10个元素,发现值为0,说明10这个位置没有使用。那么10就可以作为stream的idx进行分配,同时只要把bitset[10]置为1就行。空间回收也是类似。
2、module分配idx的方法分开表示如下:位移表示为 ((uint64_t)1 << i))
mask=0000 位移=0001,那么可以分配第一个idx为0。mask=0001
mask=0001 位移=0001,跳过;mask=0001 位移=0010,可以分配第二个idx为1。mask=0011
for (size_t i = 0; i < GetMaxModuleNumber(); i++) {
if (!(module_id_mask_ & ((uint64_t)1 << i))) {
module_id_mask_ |= (uint64_t)1 << i;
return i;
}mask的中间状态 mask = 00000000001111111,假如要找2这个idx是否分配,对1进行左移2,得到000...000100,将它与mask进行与操作,如果结果为1,则2这个idx已经分配;如果为0,则2这个idx未分配。
IdxManager::ReturnModuleIdx(size_t id_)这个方法用了 module_id_mask_ &= ~(1 << id_) ,个人理解是为了把当前id_这个idx返回给索引池,因此调用这个函数之后module_id_mask_在id_这个位置为0。
对于IdxManager类的大致用法目前探索到这里,希望大佬们有时间能分享一下漏掉的知识点。
热门帖子
精华帖子