打开微信,使用扫一扫进入页面后,点击右上角菜单,
点击“发送给朋友”或“分享到朋友圈”完成分享
基于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 IdxManager
1、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类的大致用法目前探索到这里,希望大佬们有时间能分享一下漏掉的知识点。
热门帖子
精华帖子