以STL::map实现引用表的一种方式
来源:互联网 发布:linux avi 转mp4 编辑:程序博客网 时间:2024/06/04 19:44
一直受惠于EasyDarWin开源项目,因此把自己的一些想法分享出来,希望能够帮助到其他人。
之前在推流测试中出现引用表异常的情况,经跟踪发现是内部封装的哈希表的hash函数对于传入的字符串无法得到一个唯一的key,下面是具体的hash函数
UInt32 OSRefTableUtils::HashString(StrPtrLen* inString){ Assert(inString != NULL); Assert(inString->Ptr != NULL); Assert(inString->Len > 0); if (inString == NULL || inString->Len == 0 || inString->Ptr == NULL) return 0; //make sure to convert to unsigned here, as there may be binary //data in this string UInt8* theData = (UInt8*)inString->Ptr; //divide by 4 and take the characters at quarter points in the string, //use those as the basis for the hash value UInt32 quarterLen = inString->Len >> 2; return (inString->Len * (theData[0] + theData[quarterLen] + theData[quarterLen * 2] + theData[quarterLen * 3] + theData[inString->Len - 1]));}其实对于hash函数本没没有什么错误,但我们的应用场景是对于一个传入的不同字符串参数,总能够可以进行快速的查询、插入等,而hash表从本质上来说是不可能避免冲突的,因此在此考虑使用在map的基础上来设计引用表。
在引用表的设计中参考了原Darwin的设计,并保持接口几乎一致,这样就比较便于修改。其中关键点有两个:1是对map的互斥和同步操作,在数据结构的设计上加入了互斥操作,可以放心的去调用。2是当释放对象时,该对象的引用必须为0,否则会产生不可想象的错误。下面看一下具体实现
#include "OSCond.h"#include "OSHeaders.h"class OSRefTableEx{public:class OSRefEx{private:void *mp_Object;//引用的对象或其余数据int m_Count;//当前引用对象计数,只有为0时才允许对象销毁OSCond m_Cond;//to block threads waiting for this ref.public:OSRefEx():mp_Object(NULL),m_Count(0){}OSRefEx(void * pobject):mp_Object(pobject),m_Count(0){}public:void *GetObjectPtr(){return mp_Object;}int GetRefNum(){return m_Count;}OSCond *GetCondPtr(){return &m_Cond;}void AddRef(int num){m_Count+=num;}};private:map<string,OSRefTableEx::OSRefEx*> m_Map;//以string为key,以OSRefEx为valueOSMutex m_Mutex;//提供对map的互斥操作public:OSRefEx * Resolve(string keystring);//引用对象OS_Error Release(string keystring);//释放引用OS_Error Register(string keystring,void* pobject);//加入到map中OS_Error UnRegister(string keystring);//从map中移除OS_Error TryUnRegister(string keystring);//尝试移除,如果引用为0,则移除并返回true,否则返回falsepublic:int GetEleNumInMap(){return m_Map.size();}//获得map中的元素个数OSMutex *GetMutex(){return &m_Mutex;}//给外面提供互斥接口map<string,OSRefTableEx::OSRefEx*> *GetMap(){return &m_Map;}};可以看到,引用表封装的map的key和value类型分别为string和OSRefEx*,使用string作为key是为了满足应用场景以及方便对原引用表进行修改,比较重要的是作为value的
OSRefEx*类型。OSRefex的设计参考了原OSRef类,提取了3个重要的属性来作为其成员变量。mp_Object表示string对应的对象指针,m_Count表示了对引用对象的引用次数,而m_Cond用于安全的来进行引用和释放引用。
有了OSRefex的设计,那么对于引用表的操作就是一些简单的map的增、删、查询操作了,相信对照代码一定可以看的很明白。
源码在下载频道,如发现错误,欢迎指教。
0 0
- 以STL::map实现引用表的一种方式
- 使用C++STL的map容器实现一种命令映射
- 关于Intent传输Map,List的一种实现方式
- 引用计数的一种实现
- 一种给Map赋值的优雅方式
- STL/map的遍历和初始化方式
- 以实践的方式学习C++ &(引用)
- MVC的一种实现方式
- hotfix 的一种实现方式
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- Mybatis返回Map的一种实现
- 一种引用计数机制的实现
- Python subprocess 死锁
- 根据ImageView的大小来压缩Bitmap,避免OOM
- 右值引用
- View.setRotation() 结合 View.setTranslationX(),View.setTranslationX()
- Android IPC 之Messenger
- 以STL::map实现引用表的一种方式
- springmvc 中ajax传输数据(对象)
- 第2章第2节练习题2 使用栈模拟队列操作
- java 类的继承体系
- 实现虚拟机VMware上linux与windows互相复制与粘贴
- PCM操作
- 广告轮播条升级版
- nefu 169 步步惊心
- Android 使用WebView