2017-06-30 50 views
0

我正面临基于MultiIndex容器中迭代器的Projected值的排序问题。以下是完整的代码。我在这里删除的是SellOrderRecord的调用,因为调用的函数与GenerateData相同,但预期结果不同,与前10名最小记录,而在BuyOrderRecord应导致前10名最大记录。来自Projected boost MultiIndex迭代器的最小值和最大值

我强制迭代到500,假设我会在该范围内得到最大/最小值,这是错误的。我需要取的是十大独特的价格,如果价格重复,请总结其数量。

Ex。价格10数量5;价格9数量4;价格8数量7 .... n

同样的情况,当我试图取得前10名最低价格与数量。

使用printf生成的result显示即使我已将其排序为std::less一条记录在购买记录末尾有Max,而另一个记录在最后有Min结果。我认为或者两者都应该是最小值到最大值或者最大值到最小值。完整的实际代码是共享的。

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; 
} 
+1

无论您做什么,请将您的示例自包含(http://sscce.org,https://stackoverflow.com/help/mcve)。这里是你的示例:https://gist.github.com/sehe/17cd706db4153f5321a43b0b78900339请注意,格式是人类 – sehe

回答

1

您从不检查std::next(it2, icount)的结果是否有效。

很可能,事实并非如此。毕竟it2只是_TKN找到的元素,按有序价格指数进行投影。如果_TKN恰好具有最高价在Order_Set,然后it2已经在

Price_View::const_iterator it2 = OrderRecord.first->project<PRICEVIEW>(t1); 

的最后一个元素这意味着,事件刚刚递增1将返回物价指数的end()

它在我看来像你错误地认为“投影”一个迭代器会投影到一个过滤子集,情况并非如此。它只是投射到另一个索引上。全套。

如果你确实希望能够遍历匹配的最高价格令牌的所有记录,你会更喜欢使用组合键:

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)); 
+0

谢谢@sehe它的工作。对不完整的样品感到抱歉。 –