Boost侵入式容器设计

此篇博客的目标:

    1.解释何为boost侵入式容器

    2.利用boost侵入式容器实现根据不同变量做键来进行排序


一、什么是侵入式?

侵入式容器是一个相对的概念,其对立的就是非侵入式容器,比如STL的vector、map等。侵入式容器在此阶段可以简单的被想象成熟识的链表或者树。

一个例子:

一个对象有两个属性,抽象成 int a_; string b_;

如果要分别按两个属性有序存储以上五个实例

// 第一种以非侵入式容器vector

struct test{  int a_; string b_;

// 其他成员函数

};

test a,b,c,d,e; //初始化工作

std::vector<test> test_list1,test_list2; //两个队列以不同的成员排序

test_list1.insert(a);test_list2.insert(a); 

test_list1.insert(b);test_list2.insert(b); 

test_list1.insert(c); test_list2.insert(c);  

test_list1.insert(d); test_list2.insert(d);  

test_list1.insert(e);test_list2.insert(e);

// 第二种以侵入式链表实现

struct test{ int a_; string b_; test *a_next; test *b_next;

// 其他成员函数

};

test *a,*b,*c,*d,*e, *dummy; // 初始化工作(malloc)

a->a_next = b;b->a_next = c;.......// 按照a_排序

a->b_next = b; b->b_next = c;........// 按照b_排序

上面以一个例子建立关于侵入式容器和非侵入式容器的直观印象。根据以上例子,简单总结侵入式和非侵入式容器的区别:

    1.侵入式容器的元素本身有除数据之外的属性,如指针。这样侵入式容器才成型。

    2.非侵入式容器存储元素时要进行复制,如上面,以两种属性进行排序,声明两个容器,每个a,b,c,d,e实例都存在两份。而侵入式容器不涉及复制,内存只存在一份数据。

二、上面的例子以boost侵入式该怎么实现?

#include<intrusive/...> // 引入相关库文件

strcut test{  int a_; string b_;

slist_member_hook<> a_hook_; // 为按照a_排序声明的挂钩,相当于前面的a_next;

slist_member_hook<> b_hook_; // 为b_声明的挂钩......

// a_和b_各自的比较函数(比较函数可以声明定义在外部)

struct a_compare{bool operator()(const test &l, const test &r){return l.a_ < r.a_;}};

struct a_compare{bool operator()(const test &l, const test &r){return l.a_ < r.a_;}};

};

// 以a_作比较的容器

typedef member_hook<test, slist_member_hook<>, &test::a_hook_> a_option;

typedef slist<test, a_option, compare<test::a_compare>> a_list;

// 以b_作比较的容器

typedef member_hook<test, slist_member_hook<>, &test::b_hook_> b_option;

typedef slist<test, b_option, compare<test::b_compare>> b_list; 

test a,b,c,d,e; //初始化

// a_和b_容器的使用

a_list.push_back(a); b_list.push_back(a);

a_list.push_back(b); b_list.push_back(b);

a_list.push_back(c); b_list.push_back(c);

a_list.push_back(d); b_list.push_back(d);

a_list.push_back(e); b_list.push_back(e);

可以看到,设计完成的侵入式容器在使用上和非侵入式容器一致,但是其本质上还是侵入式容器,即a,b,c,d,e虽然以不同成员变量做排序但是内存中其只有一份数据。

boost库的intrusive有两种使用方法,之一是上面用到的方法以成员变量的形式被声明于类中,称为挂钩;另一种是以基类的方式被用户继承实现。

三、生产环境中boost/intrusive的使用

至此,boost/intrusive的基本使用介绍完毕,下面以一个例子详细展示其使用细节。

现在有一个需求,其实就是分布式计算平台的内部数据结构:

    1.每当Master服务器收到新的计算节点的上线连接请求时,为每个请求分配一个唯一的id,并且将其id和对应的ip保存起来。此过程是计算节点的注册过程

    2.当有若干个计算任务到来时,将若干个任务分配到已经注册的节点。由计算节点来执行具体的计算任务。

非侵入式设计

那么在非侵入式容器背景下,数据结构的设计可能会是如下所示:

    首先创建一个map<int, string> slaveList,用以保存所有注册的计算节点。int是节点id,string是节点ip。然后为了记录每个计算任务被分配到哪一个计算节点,再创建一个map<int, int> allocateList,key是计算任务的id,value是计算节点id。最后为了效率问题,需要一个队列来保存每个计算节点在运行哪些任务,所以创建multimap<int, int> loadList,key是计算节点id,vlaue是任务id。

那么当计算节点的某个任务完成之后,就可以删除allcoateList和loadList对于的任务;当计算节点宕机,删除slaveList相应字段,并删除allocateList和loadList相应的任。

以上就是非侵入式容器的设计思路。

侵入式设计


task定义


slave定义


slave定义

基本声明和非侵入式没有太多差别,仅仅是在类定义中增加了相应的挂钩用来做排序用。着重阅读挂钩的声明和以相应挂钩定义的容器。

四、实践排雷

时刻牢记,在还有容器指向某个元素时而删除元素会引发错误。这个错误产生根源和链表指针指向的元素被删除是相同的。所以在初始化和删除时都要格外小心。初始化时不要让指针指向局部变量,因为局部变量被系统回收时就会产生和删除时一样的错误。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容