Projected boost MultiIndex 迭代器的最小值和最大值
Min & Max Value from Projected boost MultiIndex iterator
我遇到了基于 MultiIndex 容器中迭代器的投影值的排序问题。下面是完整的代码。我在这里删除的是 SellOrderRecord
的调用,因为调用的函数相同 GenerateData
但预期结果不同,即;在 BuyOrderRecord
时拥有前 10 条最小记录应该会产生前 10 条最大记录。
我正在强行迭代到 500,假设我会得到该范围内的 Max/Min 值,这是错误的。我需要获取的是前 10 个唯一价格,如果重复价格,则对其数量求和。
例如。价格 10 数量 5;价格 9 数量 4;价格 8 数量 7 .... n
当我尝试获取带数量的前 10 个最低价格时也是如此。
即使我用 std::less
对使用 printf 生成的 result 进行了排序,结果显示 result在末尾。我认为要么两者都应该是最小值到最大值,要么是最大值到最小值。完整的实际代码已共享。
namespace bip = boost::interprocess;
namespace bmi = boost::multi_index;
struct MIOrder_Message /// For Data
{
// STREAM_HEADER Global_Header;
// char Message_Type;
MIOrder_Message(Order_Message _Ord)
: Timestamp(_Ord.Timestamp), Order_Id(_Ord.Order_Id), Token(_Ord.Token),
Order_Type(_Ord.Order_Type), Price(_Ord.Price),
Quantity(_Ord.Quantity) {
// std::cout << " Insert data for Token "<< _Ord.Token<<std::endl;
}
long Timestamp;
double Order_Id;
int Token;
char Order_Type;
int Price;
int Quantity;
};
/// Order_Message and MIOrder_Message are almost identical
typedef bip::allocator<MIOrder_Message,
bip::managed_shared_memory::segment_manager>
shared_struct_allocator;
enum {
ORDERVIEW,
TOKENVIEW,
PRICEVIEW,
TYPEVIEW,
};
typedef bmi::multi_index_container<
MIOrder_Message,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<struct Order_Id>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, double, MIOrder_Message::Order_Id)>,
bmi::ordered_non_unique<bmi::tag<struct Token>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Token)>,
bmi::ordered_non_unique<bmi::tag<struct Price>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Price), std::less<int>>,
bmi::ordered_non_unique<bmi::tag<struct Order_Type>, BOOST_MULTI_INDEX_MEMBER(MIOrder_Message, char, Order_Type)> >,
shared_struct_allocator
> Order_Set;
typedef bmi::nth_index<Order_Set, ORDERVIEW>::type Order_view;
typedef bmi::nth_index<Order_Set, TOKENVIEW>::type Token_View;
typedef bmi::nth_index<Order_Set, PRICEVIEW>::type Price_View;
typedef std::map<int, int> _PricePoint;
_PricePoint GenerateData(int _TKN, std::pair<Order_Set *, std::size_t> OrderRecord, bool IsReverse = false) {
_PricePoint CurrentPrice;
if (OrderRecord.second > 0) {
Token_View::const_iterator t1 =
OrderRecord.first->get<TOKENVIEW>().find(_TKN);
Price_View::const_iterator it2 = OrderRecord.first->project<PRICEVIEW>(t1);
int icount = 0;
int Price = 0;
while (icount < 500)
/// I am forcefully iterating to 500 assuming that i will
/// get Max value within that range. What i need to fetch is
/// Top 10 unique Price and sum its Qty if Price is repeated.
/// Ex. Price 10 Qty 5 ; Price 9 Qty 4; Price 8 Qty 7 .... n
/// Same is the case when I am trying to fetch top 10 Min Price with Qty.
{
auto val = std::next(it2, icount);
if (val->Token == _TKN) {
// printf(" Bid Data Found for token %d , Price %d , Qty %d , Time %li
// , OrderNumber %16f , icount %d \n
// ",val->Token,val->Price,val->Quantity,val->Timestamp,val->Order_Id,icount);
CurrentPrice[val->Price] += val->Quantity;
Price = val->Price;
}
icount++;
}
std::cout << " Bid Price " << Price << std::endl;
}
return CurrentPrice;
}
int main() {
bip::managed_shared_memory segment(bip::open_or_create, "mySharedMemory", 20ull<<20);
Order_Set::allocator_type alloc(segment.get_segment_manager());
Order_Set * BuyOrderRecord = segment.find_or_construct<Order_Set>("MCASTPORT0BUY")(alloc);
if (BuyOrderRecord->empty()) {
}
while (true) {
int _TKN = 49732;
_PricePoint CurrentPrice = GenerateData(_TKN, std::make_pair(BuyOrderRecord, 1), true);
std::cout << "=========================================================" << std::endl;
sleep(2);
}
return 0;
}
你永远不会检查 std::next(it2, icount)
的结果是否有效。
很可能不是。毕竟 it2
只是 _TKN
找到的元素,投影在有序价格指数上。如果 _TKN
恰好在 Order_Set 中具有最高价格,那么 it2
已经是
中的最后一个元素
Price_View::const_iterator it2 = OrderRecord.first->project<PRICEVIEW>(t1);
这意味着仅增加 1 的事件将 return end()
价格指数。
在我看来,您错误地认为 "projecting" 迭代器会投射到 过滤子集 中,但事实并非如此。它只是投影到另一个索引上。全套的。
如果您确实希望能够迭代匹配最高价格的令牌的所有记录,您会更喜欢使用复合键:
typedef bmi::multi_index_container<
MIOrder_Message,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<struct Order_Id>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, double, MIOrder_Message::Order_Id)>,
bmi::ordered_non_unique<bmi::tag<struct Token>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Token)>,
bmi::ordered_non_unique<bmi::tag<struct Price>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Price), std::less<int>>,
bmi::ordered_non_unique<bmi::tag<struct Order_Type>, BOOST_MULTI_INDEX_MEMBER(MIOrder_Message, char, Order_Type)>
, bmi::ordered_non_unique<bmi::tag<struct Composite>,
bmi::composite_key<MIOrder_Message,
bmi::member<MIOrder_Message, int, &MIOrder_Message::Token>,
bmi::member<MIOrder_Message, int, &MIOrder_Message::Price>
>
>
>,
shared_struct_allocator
> Order_Set;
有序组合键接受部分键,因此您可以:
auto range = OrderRecord.first->get<Composite>().equal_range(boost::make_tuple(_TKN));
我遇到了基于 MultiIndex 容器中迭代器的投影值的排序问题。下面是完整的代码。我在这里删除的是 SellOrderRecord
的调用,因为调用的函数相同 GenerateData
但预期结果不同,即;在 BuyOrderRecord
时拥有前 10 条最小记录应该会产生前 10 条最大记录。
我正在强行迭代到 500,假设我会得到该范围内的 Max/Min 值,这是错误的。我需要获取的是前 10 个唯一价格,如果重复价格,则对其数量求和。
例如。价格 10 数量 5;价格 9 数量 4;价格 8 数量 7 .... n
当我尝试获取带数量的前 10 个最低价格时也是如此。
即使我用 std::less
对使用 printf 生成的 result 进行了排序,结果显示 result在末尾。我认为要么两者都应该是最小值到最大值,要么是最大值到最小值。完整的实际代码已共享。
namespace bip = boost::interprocess;
namespace bmi = boost::multi_index;
struct MIOrder_Message /// For Data
{
// STREAM_HEADER Global_Header;
// char Message_Type;
MIOrder_Message(Order_Message _Ord)
: Timestamp(_Ord.Timestamp), Order_Id(_Ord.Order_Id), Token(_Ord.Token),
Order_Type(_Ord.Order_Type), Price(_Ord.Price),
Quantity(_Ord.Quantity) {
// std::cout << " Insert data for Token "<< _Ord.Token<<std::endl;
}
long Timestamp;
double Order_Id;
int Token;
char Order_Type;
int Price;
int Quantity;
};
/// Order_Message and MIOrder_Message are almost identical
typedef bip::allocator<MIOrder_Message,
bip::managed_shared_memory::segment_manager>
shared_struct_allocator;
enum {
ORDERVIEW,
TOKENVIEW,
PRICEVIEW,
TYPEVIEW,
};
typedef bmi::multi_index_container<
MIOrder_Message,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<struct Order_Id>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, double, MIOrder_Message::Order_Id)>,
bmi::ordered_non_unique<bmi::tag<struct Token>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Token)>,
bmi::ordered_non_unique<bmi::tag<struct Price>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Price), std::less<int>>,
bmi::ordered_non_unique<bmi::tag<struct Order_Type>, BOOST_MULTI_INDEX_MEMBER(MIOrder_Message, char, Order_Type)> >,
shared_struct_allocator
> Order_Set;
typedef bmi::nth_index<Order_Set, ORDERVIEW>::type Order_view;
typedef bmi::nth_index<Order_Set, TOKENVIEW>::type Token_View;
typedef bmi::nth_index<Order_Set, PRICEVIEW>::type Price_View;
typedef std::map<int, int> _PricePoint;
_PricePoint GenerateData(int _TKN, std::pair<Order_Set *, std::size_t> OrderRecord, bool IsReverse = false) {
_PricePoint CurrentPrice;
if (OrderRecord.second > 0) {
Token_View::const_iterator t1 =
OrderRecord.first->get<TOKENVIEW>().find(_TKN);
Price_View::const_iterator it2 = OrderRecord.first->project<PRICEVIEW>(t1);
int icount = 0;
int Price = 0;
while (icount < 500)
/// I am forcefully iterating to 500 assuming that i will
/// get Max value within that range. What i need to fetch is
/// Top 10 unique Price and sum its Qty if Price is repeated.
/// Ex. Price 10 Qty 5 ; Price 9 Qty 4; Price 8 Qty 7 .... n
/// Same is the case when I am trying to fetch top 10 Min Price with Qty.
{
auto val = std::next(it2, icount);
if (val->Token == _TKN) {
// printf(" Bid Data Found for token %d , Price %d , Qty %d , Time %li
// , OrderNumber %16f , icount %d \n
// ",val->Token,val->Price,val->Quantity,val->Timestamp,val->Order_Id,icount);
CurrentPrice[val->Price] += val->Quantity;
Price = val->Price;
}
icount++;
}
std::cout << " Bid Price " << Price << std::endl;
}
return CurrentPrice;
}
int main() {
bip::managed_shared_memory segment(bip::open_or_create, "mySharedMemory", 20ull<<20);
Order_Set::allocator_type alloc(segment.get_segment_manager());
Order_Set * BuyOrderRecord = segment.find_or_construct<Order_Set>("MCASTPORT0BUY")(alloc);
if (BuyOrderRecord->empty()) {
}
while (true) {
int _TKN = 49732;
_PricePoint CurrentPrice = GenerateData(_TKN, std::make_pair(BuyOrderRecord, 1), true);
std::cout << "=========================================================" << std::endl;
sleep(2);
}
return 0;
}
你永远不会检查 std::next(it2, icount)
的结果是否有效。
很可能不是。毕竟 it2
只是 _TKN
找到的元素,投影在有序价格指数上。如果 _TKN
恰好在 Order_Set 中具有最高价格,那么 it2
已经是
Price_View::const_iterator it2 = OrderRecord.first->project<PRICEVIEW>(t1);
这意味着仅增加 1 的事件将 return end()
价格指数。
在我看来,您错误地认为 "projecting" 迭代器会投射到 过滤子集 中,但事实并非如此。它只是投影到另一个索引上。全套的。
如果您确实希望能够迭代匹配最高价格的令牌的所有记录,您会更喜欢使用复合键:
typedef bmi::multi_index_container<
MIOrder_Message,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<struct Order_Id>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, double, MIOrder_Message::Order_Id)>,
bmi::ordered_non_unique<bmi::tag<struct Token>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Token)>,
bmi::ordered_non_unique<bmi::tag<struct Price>, BOOST_MULTI_INDEX_MEMBER( MIOrder_Message, int, MIOrder_Message::Price), std::less<int>>,
bmi::ordered_non_unique<bmi::tag<struct Order_Type>, BOOST_MULTI_INDEX_MEMBER(MIOrder_Message, char, Order_Type)>
, bmi::ordered_non_unique<bmi::tag<struct Composite>,
bmi::composite_key<MIOrder_Message,
bmi::member<MIOrder_Message, int, &MIOrder_Message::Token>,
bmi::member<MIOrder_Message, int, &MIOrder_Message::Price>
>
>
>,
shared_struct_allocator
> Order_Set;
有序组合键接受部分键,因此您可以:
auto range = OrderRecord.first->get<Composite>().equal_range(boost::make_tuple(_TKN));