boost multi_index
/**
boost 多索引容器的一般使用
这里使用google 的gmock 库来验证对boost 多索引模板的使用,并验证。
这里是手敲的,可能会有一些字符敲错的情况,编译错误的放,修改一下,同时链接gmock库就可以正常运行了。
当然还需要链接boost 的相关库
**/ #include <stdint.h> #include <gtest/gtest.h>
#include <gmock/gmock.h> #include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/global_fun.hpp> // 多索引的结构或者类
struct stru_AccountFeeIncre
{
int64_t nAccountID;
int32_t nGoodsID;
int32_t nGoodsGroupID;
int32_t nFeeMode;
int32_t nTradeMode;
double dFeeValue;
}; // 为索引的Key 定义一个标志类型,类似std::map 的Key
struct tagGoodsID {};
struct tagGoodsGroupID {}; // 声明多索引结构,主要绑定索引类型可以与指定成员的一一映射
using MultiIndexFeeIncre =
boost::multi_index::multi_index_container<
stru_AccountFeeIncre, // 数据结构,用于索引的对象
boost::multi_index::indexed_by< // 创建索引,可以是一个或者多个。分别以',' 分隔
// 创建唯一索引,不允许插入该字段的值相同的两个对象到此容器中。
boost::multi_index::ordered_unique<
boost::multi_index::tag<tagGoodsID>, // 索引标签
BOOST_MULTI_INDEX_MEMBER(struAccountFeeIncre, int32_t, nGoodsID) // 该索引绑定的成员
>,
// 创建非唯一索引,允许多个相同的值到此容器中
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<tagGoodsGroupID>,
BOOST_MULTI_INDEX_MEMBER(stru_AccountFeeIncre, int32_t, nGoodsGroupID)
>
>
>; using C_ITER_FEE_INCRE = MultiIndexFeeIncre::const_iterator;
using PAIR_RANGE_FEE_INCRE = std::pair<C_ITER_FEE_INCRE, C_ITER_FEE_INCRE>;
using C_ITER_ID_FEE_INCRE = MultiIndexFeeIncre::index<tagGoodsID>::type::const_iterator;
using C_ITER_GROUP_FEE_INCRE = MultiIndexFeeIncre::index<tagGoodsGroupID>::type::const_iterator;
using PAIR_RANGE_GROUP_FEE_INCRE = std::pair<C_ITER_GROUP_FEE_INCRE, C_ITER_GROUP_FEE_INCRE>; // 定义多索引容器实例
static MultiIndexFeeIncre s_multiAccountFeeIncre;
// 定义容器的索引实例的引用 - 非const 版本
static MultiIndexFeeIncre::index<tagGoodsID>::type &INDEX_ID_FEE_INCRE = s_multiAccountFeeIncre.get<tagGoodsID>();
static MultiIndexFeeIncre::index<taggoodsGroupID>::type &INDEX_GROUP_FEE_INCRE = s_multiAccountFeeIncre.get<tagGoodsGroupID>();
// 定义容器的索引实例的引用 - const 版本
static const MultiIndexFeeIncre::index<tagGoodsID>::type &C_INDEX_ID_FEE_INCRE = s_multiAccountFeeIncre.get<tagGoodsID>();
static const MultiIndexFeeIncre::index<tagGoodsgroupID>::type &C_INDEX_GROUP_FEE_INCRE = s_multiAccountFeeIncre.get<tagGoodsGroupID>(); // template 版本
MultiIndexFeeIncre::template index<tagGoodsID>::type &TPLT_INDEX_ID = s_multiAccountFeeIncre.template get<taggoodsID>();
MultiIndexFeeIncre::template index<tagGoodsGroupID>::type &TPLT_INDEX_GROUP = s_multiAccountFeeIncre.template get<tagGoodsGroupID>(); TEST(TestBoostUse, MultiIndex)
{
const int32_t GROUP_ID_01 = ;
const int32_t GROUP_ID_02 = ;
int64_t nExpectSize = ; EXPECT_EQ(nExpectSize, s_multiAccountFeeIncre.size()); int64_t nGoodsID = ;
stru_AccountFeeIncre stFeeIncre;
stFeeIncre.nAccountID = ;
stFeeIncre.nGoodsID = nGoodsID;
stFeeIncre.nGoodsGroupID = GROUP_ID_01;
stFeeIncre.nFeeMode = ;
stFeeIncre.nTradeMode = ;
stFeeIncre.dFeeValue = 0.5; // 商品组1
int32_t nExpectSizeGroupID_1 = ;
// 插入一条
s_multiAccountFeeIncre.emplace(stFeeIncre);
++nExpectSize;
++nExpectSizeGroupID_1;
EXPECT_EQ(nExpectSize, s_multiAccountFeeIncre.size()); // 插入与唯一索引相同的值的对象,插入失败
s_multiAccountFeeIncre.emplace(stFeeIncre);
EXPECT_EQ(nExpectSize, s_multiAccountFeeIncre.size()); // 插入一条
++nGoodsID;
stFeeIncre.nGoodsID = nGoodsID;
stFeeIncre.nGoodsGroupID = GROUPID_01; s_multiAccountFeeIncre.emplace(stFeeIncre);
++nExpectSize;
++nExpectSizeGroupID_1;
EXPECT_EQ(nExpectSize, s_multiAccountfeeIncre.size()); // 插入一条
++nGoodsID;
stFeeIncre.nGoodsID = nGoodsID;
stFeeIncre.nGoodsGroupID = GROUP_ID_01; s_multiAccountFeeIncre.emplace(stFeeIncre);
++nExpectSize;
++nExpectSizeGroupID_1;
EXPECT_EQ(nExpectSize, s_multiAccountFeeIncre.size()); // 插入到另一个商品组
int32_t nExpectSizeGroupID_2 = ;
++nGoodsID;
stFeeIncre.nGoodsID = nGoodsID;
stFeeIncre.nGoodsGroupID = GROUP_ID_02; s_multiAccountFeeIncre.emplace(stFeeIncre);
++nExpectSize;
++nExpectSizeGroupID_2;
EXPECT_EQ(nExpectSize, s_multiAccountFeeIncre.size()); // 插入一条
++nGoodsID;
stFeeIncre.nGoodsID = nGoodsID;
stFeeIncre.nGoodsGroupID = GROUP_ID_02; s_multiAccountFeeIncre.emplace(stFeeIncre);
++nExpectSize;
++nExpectSizeGroupID_2;
EPXECT_EQ(nEpxectSize, s_multiAccountFeeIncre.size()); // 查询
do
{
// 唯一索引的查询,结果仅有一条记录
int nTempGoodsID = ;
C_ITER_ID_FEE_INCRE c_iter_id = INDEX_ID_FEE_INCRE.find(nTempGoodsID);
ASSERT_NE(c_iter_id, INDEX_ID_FEE_INCRE.end()); // 非唯一索引的查询,结果为一组记录
PAIR_RANGE_GROUP_FEE_INCRE range = TPLT_INDEX_GROUP.equal_range(GROUP_ID_01);
int nTempSize = ;
for (auto it = range.first; it != range.second; ++it)
{
EXPECT_EQ(GROUP_ID_01, it->nGoodsGroupID);
++nTempSize;
} EXPECT_EQ(nExpectSizeGroupID_1, nTempSize);
}
while (false); // 修改
do
{
// 拷贝副本
MultiIndexFeeIncre bak_multiAccountFeeIncre = s_multiAccountFeeIncre;
int32_t bakExpectSize = nExpectSize;
int32_t nTempGoosdID = ; C_ITER_ID_FEE_INCRE c_iter_id = bak_multiAccountFeeIncre.get<tagGoodsID>().find(nTempGoodsID);
EXPECT_NE(c_iter_id, bak_multiAccountFeeIncre.get<tagGoodsID>().end());
if (c_iter_id == bak_multiAccountFeeIncre.get<tagGoodsID>().end())
{
break;
} stru_AccountFeeIncre newObj; // 未设置值使用内存随机值即可
newObj.nGoodsID = c_iter_id->nGoodsID; // 唯一性主键不修改
newObj.nGoodsGroupID = nExpectSizeGroupID_2; // 商品组ID改到2 非唯一性主键修改
bool bResTemp = bak_multiAccountfeeIncre.replace(c_iter_id, newObj);
EXPECT_TRUE(bResTemp);
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size());
}
while (false); do
{
// 拷贝副本
MultiIndexFeeIncre bak_multiAccountFeeIncre = s_multiAccountFeeIncre;
int32_t bakExpectSize = nExpectSize;
int32_t nTempGoodsID = ; C_ITER_ID_FEE_INCRE c_iter_id = bak_multiAccountFeeIncre.get<tagGoodsID>().find(nTempGoodsID);
EXPECT_NE(c_iter_id, bak_multiAccountFeeIncre.get<tagGoodsID>().end());
if (c_iter_id == bak_multiAccountFeeIncre.get<tagGoodsID>().end())
{
break;
} stru_AccountFeeIncre newObj;
newObj.nGoodsID = ; // 修改唯一性主键
newObj.nGoodsGroupID = c_iter_id->nGoodsGroupID; // 非唯一性主键不修改
bool bResTemp = bak_multiAccountFeeIncre.replace(c_iter_id, newObj);
EXPECT_TRUE(bResTemp);
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size());
}
while (false); // 删除
do
{
// 拷贝副本
MultiIndexFeeIncre bak_multiAccountFeeIncre = s_multiAccountFeeIncre;
int32_t bakExpectSize = nExpectSize;
int32_t bakExpectSizeGroupID_1 = nExpectSizeGroupID_1; // 先删除商品组1 中的一个商品
int nTempGoodsID = ;
C_ITER_ID_FEE_INCRE c_iter_id = bak_multiAccountFeeIncre.get<tagGoodsID>().find(nTempGoodsID);
ASSERT_NE(c_iter_id, bak_multiAccountFeeIncre.get<taggoodsID>().end());
bak_multiAccountFeeIncre.erase(c_iter_id);
--bakExpectSize;
--bakExpectSizeGroupID_1;
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size()); // 删除商品组1 的元素
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.get<tagGroupID>().size());
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.get<tagGoodsGroupID>().size());
bak_multiAccountFeeIncre.template get<tagGoodsGroupID>().erase(GROUP_ID_01);
bakExpectSize -= bakExpectSizeGroupID_1;
bakExpectSizeGroupID_1 = ;
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size());
}
while (false); do
{
// 拷贝副本
MultiIndexFeeIncre bak_multiAccountFeeIncre = s_multiAccountFeeIncre;
int32_t bakExpectSize = nExpectSize;
int32_t bakExpectSizeGroupID_2 = nExpectSizeGroupID_2; // 删除商品组2 的元素
bak_multiAccountFeeIncre.template get<tagGoodsGroupID>().erase(GROUP_ID_02);
bakExpectSize -= bakExpectSizeGroupID_2;
bakExpectSizeGroupID_2 = ;
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size());
}
while (false); do
{
// 拷贝副本
MultiIndexFeeIncre bak_multiAccountFeeIncre = s_multiAccountFeeIncre;
int32_t bakGoodsID = nGoodsID;
int32_t bakExpectSize = nExpectSize; // 按唯一性主键: 商品ID 进行删除
do
{
bak_multiAccountFeeIncre.template get<tagGoodsID>().erase(bakGoodsID);
--bakExpectSize;
EXPECT_EQ(bakExpectSize, bak_multiAccountFeeIncre.size());
}
while (--bakGoodsID > );
}
while (false);
} int main(int argc, char *argv[])
{
testing::InitGoodsMock(&argc, argv); return RUN_ALL_TESTS();
}
boost multi_index的更多相关文章
- 使用boost::multi_index高速构建排行榜
使用boost::multi_index高速构建排行榜 前几天在boost的maillist上看到boost::multi_index将要支持ranked_index(邮件内容见附件2),这实乃我等苦 ...
- 用 boost::multi_index 管理玩家
用 boost::multi_index 管理玩家(金庆的专栏)网游服务器上的玩家集合需要多种索引:如用ID查找,角色名查找, 用登录时分配的会话ID查找.用boost::multi_index进行玩 ...
- boost::multi_index 多索引容器
#include "stdafx.h" #include <string> #include <boost/multi_index_container.hpp&g ...
- boost::multi_index 提供一种千人在线即时排行榜的设计思路
原文地址: http://www.limerence2017.com/2019/06/23/cpp01/ 做游戏或金融后台开发,经常会遇到设计开发排行榜的需求.比如玩家的充值排行,战力排行等等.而这种 ...
- boost multi_index 插入返回值
boost multi_index 对象插入函数emplace() 的返回值,是一个std::pair<iterator, bool>该pair 的first 是一个插入成功的位置,第二个 ...
- boost multi_index简单了解
#include <string> #include <iostream> #include <boost/multi_index_container.hpp> # ...
- Boost练习程序(multi_index_container)
代码来自:http://blog.csdn.net/whuqin/article/details/8482547 该容器能实现多列索引,挺好. #include <string> #inc ...
- boost asio 异步实现tcp通讯
---恢复内容开始--- asioboost 目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化 一.前言 boost asio可算是一个简 ...
- boost multi index
Boost.MultiIndex makes it possible to define containers that support an arbitrary number of interfac ...
随机推荐
- 最全的CSS浏览器兼容问题
CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理方法并整理了一下.对于web2.0的过度,请尽量用xhtml格 ...
- centos安装与卸载postgresql
1.卸载旧版本postgresql $ yum remove postgresql* 2.更新yum $ yum update 3.下载pgdg-centos92-9.2-6.noarch.rpm,或 ...
- 如何配置Windows 防火墙,允许SQL Server的远程连接
一.如何找到SQL Server正在侦听的TCP端口,可以按一下步骤: 1.打开 SQL Server 配置管理器中,从开始->所有程序-> Microsoft SQL Server 20 ...
- Android驱动开发前的准备(一)
Android系统移植与驱动开发概述 1.1 Android 系统架构 1.2 Android系统移植的主要工作 1.3 查看linux内核版本 1.4 linux内核版本号的定义规则 1.5 lin ...
- Python实例4
4.输入某年某月某日,判断这一天是这一年的第几天? 正解: 源码:
- 面试题---PHP
1.PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言. 2.echo,print和print_r的区别: echo和print都可以做 ...
- angular2 笔记
动态添加一个component: import { ViewContarinerRef, Component, ComponentFactoryResolver, ViewChild } from ' ...
- 如何通过IP地址添加网络打印机
以惠普的HP LaserJet 8100 Series PCL6为例. 1.从开始菜单选择“打印机和传真”. 2.鼠标右键“添加打印机”,然后单击“下一步”,选择“连接到这台计算机的本地打印机”,注意 ...
- Java.lang.String 乱码反编译
这个有个前提就是要知道错误的编码和应该转换的正确的编码 比如 gbk = >utf-8 可以 System.out.println("具体的乱码".getBytes(&quo ...
- Bash漏洞批量检测工具与修复方案
&amp;lt;img src="http://image.3001.net/images/20140928/14118931103311.jpg!small" t ...