/**
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的更多相关文章

  1. 使用boost::multi_index高速构建排行榜

    使用boost::multi_index高速构建排行榜 前几天在boost的maillist上看到boost::multi_index将要支持ranked_index(邮件内容见附件2),这实乃我等苦 ...

  2. 用 boost::multi_index 管理玩家

    用 boost::multi_index 管理玩家(金庆的专栏)网游服务器上的玩家集合需要多种索引:如用ID查找,角色名查找, 用登录时分配的会话ID查找.用boost::multi_index进行玩 ...

  3. boost::multi_index 多索引容器

    #include "stdafx.h" #include <string> #include <boost/multi_index_container.hpp&g ...

  4. boost::multi_index 提供一种千人在线即时排行榜的设计思路

    原文地址: http://www.limerence2017.com/2019/06/23/cpp01/ 做游戏或金融后台开发,经常会遇到设计开发排行榜的需求.比如玩家的充值排行,战力排行等等.而这种 ...

  5. boost multi_index 插入返回值

    boost multi_index 对象插入函数emplace() 的返回值,是一个std::pair<iterator, bool>该pair 的first 是一个插入成功的位置,第二个 ...

  6. boost multi_index简单了解

    #include <string> #include <iostream> #include <boost/multi_index_container.hpp> # ...

  7. Boost练习程序(multi_index_container)

    代码来自:http://blog.csdn.net/whuqin/article/details/8482547 该容器能实现多列索引,挺好. #include <string> #inc ...

  8. boost asio 异步实现tcp通讯

    ---恢复内容开始--- asioboost   目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化   一.前言 boost asio可算是一个简 ...

  9. boost multi index

    Boost.MultiIndex makes it possible to define containers that support an arbitrary number of interfac ...

随机推荐

  1. ftpget 从Windows FTP服务端获取文件

    /********************************************************************************* * ftpget 从Windows ...

  2. 常用的CSS Hack

    一.什么是CSS Hack? 不同的浏览器对CSS的解析结果是不同的,因此会导致相同的CSS输出的页面效果不同,这就需要CSS Hack来解决浏览器局部的兼容性问题.而这个针对不同的浏览器写不同的CS ...

  3. linux下的守护进程

    关于守护进程,在此会介绍一下几种: 1.screen 2.supervisord(python) 一:Screen 开始使用Screen 简单来说,Screen是一个可以在多个进程之间多路复用一个物理 ...

  4. Angularjs scope

    $scope: var myapp = angular.module('myapp', []); myapp .controller('parent', function ($scope,$timeo ...

  5. ST第二次作业,相关程序测试及测试用例

    public static int findLast(int[]x,int y){ for(int i = x.length-1;i>0;i--){//i>=0 if(x[i] == y) ...

  6. 第四篇T语言实例开发,自动加血

    游戏自动加血 基础知识复习 通过前面的学习了解以下内容: TC软件的基本使用 TC的基础语法 变量与常量 功能的使用 流程语句的使用 线程的基本使用 TC控件的基本使用 热键和按钮的事件功能 控件的数 ...

  7. Eclipse中的Link with Editor功能是如何实现

    Eclipse中的Link with Editor功能是如何实现 - kaukiyou的专栏 - 博客频道 - CSDN.NEThttp://blog.csdn.net/kaukiyou/articl ...

  8. 【转载】浅谈游戏开发之2D手游工具

    浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android  程序设计: 其它  编程语言:   引擎/SDK ...

  9. 激!QTREE系列

    我现在才开始刷 QTREE 是不是太弱了?算了不管他…… QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?) #include <cstdio> # ...

  10. malloc原理和内存碎片[转]

    当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 4.建立映射关系 ...