美文网首页
Boost侵入式容器设计

Boost侵入式容器设计

作者: 一天天就知道睡觉 | 来源:发表于2019-01-02 18:01 被阅读0次

此篇博客的目标:

    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定义

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

四、实践排雷

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

相关文章

  • Boost侵入式容器设计

    此篇博客的目标: 1.解释何为boost侵入式容器 2.利用boost侵入式容器实现根据不同变量做键来进行排序 一...

  • Spring简介

    Spring的优点: 低侵入式设计,代码污染率极低 不依赖于容器,在各种容器中都可以轻松使用,并且spring本身...

  • Spring 核心 : IOC 处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • Spring核心——IOC处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • spring框架的优势

    Spring框架的优点 1、非侵入式设计 Spring是一种非侵入式(non-invasive)框架,它可以使应用...

  • APM 探针分析

    概要 APM探针主要有侵入式探针和非侵入式探针。 其中侵入式探针以zipkin为代表,非侵入式探针以pinpoin...

  • Modern C++特性:基于范围的for循环

    遍历容器是种广泛的需求,在C++11之前,有些库提供了遍历容器内所有元素的封装方法,比如Boost中的BOOST_...

  • boost - 指针容器

    ptr_vector指针向量基本概念 ptr_vector指针向量 基本概念 Boost学习之指针容器 基本概念:...

  • AOP

    相关依赖 java动态代理 注解aop(侵入式) 非侵入式 XML配置

  • 非侵入式和侵入式区别

    非侵入式 允许在应用系统中自由选择和组装Spring框架的各个功能模块,并且不强制要求应用系统的类必须从Sprin...

网友评论

      本文标题:Boost侵入式容器设计

      本文链接:https://www.haomeiwen.com/subject/dmddlqtx.html