多索引容器 multi_index_container
为什么要使用multi_index_container
相信想必大家在实际开发中一定多少会遇到一些的问题,我需要创建一个可以索引的容器,例如map,set 但是无论map还是set 都是单索引的,例如建立一个类,类里有多个成员变量我们都要对应的索引便于查找 例如:
class Ticket
{
public:
int ticketHeight;//块高
uint256 ticketTxHash;//票hash
CAmount ticketPrice;//当前票的票价
CBitcoinAddress ticketAddress;//买票的地址
Ticket();
Ticket(const Ticket& ticket);
Ticket(int ticketHeight, uint256 ticketTxHash, CAmount ticketPrice, CBitcoinAddress ticketAddress);
void operator=(Ticket & ticket)
{
this->ticketAddress = ticket.ticketAddress;
this->ticketHeight = ticket.ticketHeight;
this->ticketPrice = ticket.ticketPrice;
this->ticketTxHash = ticket.ticketTxHash;
}
bool operator==(Ticket ticket)
{
if (this->ticketAddress == ticket.ticketAddress &&
this->ticketHeight == ticket.ticketHeight &&
this->ticketTxHash == ticket.ticketTxHash &&
this->ticketPrice == ticket.ticketPrice)
{
return true;
}
return false;
}
std::string toString();
~Ticket();
private:
};
我需要对ticketHeight,ticketTxHash 经行排序索引,如果只是使用map,set构建索引的话,只能对应一种索引,ticketTxHash 或者ticketHeight,而我们需要使用两个map或者set才可以完成对应的需求,那么有没有一种结构可以对应两个排序索引——答案是有的 就是我们要说的 boost库中的 multi_index_container
下面就来说一下 multi_index_container 的基本使用,以及我遇到的坑,希望大家不要踩到;
创建
multi_index_container可以看作加载在内存中的数据库,不多说直接上代码
struct ticket_tx_hash {};//为排序索引后表建立的表明()
struct ticket_height {};
typedef
boost::multi_index_container<
Ticket, //此处为你要排序的成员类名
indexed_by< //indexed_by<...> 中填写索引规则
ordered_unique< //ordered_unique 类比数据库中的主键为唯一索引,ordered默认升序,还有其他顺序下面会做具体描述
//tag<...> 指定表名 需要声明即上面的结构体名
//BOOST_MULTI_INDEX_MEMBER boost的宏,表示在目标中选取成员作为排序依据
//(Ticket, uint256, ticketTxHash) Ticket:容器成员 uint256:排序依据的类型 ticketTxHash :排序依据
tag<ticket_tx_hash>, BOOST_MULTI_INDEX_MEMBER(Ticket, uint256, ticketTxHash)>,
ordered_non_unique<//非唯一索引——可与存在多个
tag<ticket_height>, BOOST_MULTI_INDEX_MEMBER(Ticket, int, ticketHeight)>
>
> ticketpool_set;
ticketpool_set ticket_pool;
这样就完成了一个多索引容器类型ticketpool_set的建立,接着实例化了一个ticketpool_set类型的ticket_pool
补充1 :排序不止ordered_unique/ordered_non_unique一种,还有hashed_unique,下面是一段比特币mempool代码,以及指定排序规则
typedef boost::multi_index_container<
CTxMemPoolEntry,
boost::multi_index::indexed_by<
// hashed_unique 按照hash排序
boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>,
//指定排序规则 CompareTxMemPoolEntryByDescendantScore
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<descendant_score>,
boost::multi_index::identity<CTxMemPoolEntry>,
CompareTxMemPoolEntryByDescendantScore
>,
。。。。//省略