2017-06-30 53 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它的工作。對不完整的樣品感到抱歉。 –