2017-06-30 10 views
0

MultiIndexコンテナのイテレータからのProjected値に基づいてソートの問題が発生しています。以下は完全なコードです。ここで削除したのは、呼び出される関数が同じGenerateDataであるため、SellOrderRecordの呼び出しですが、期待される結果が異なります。トップ10のミニレコードで、BuyOrderRecordでトップ10の最大レコードになるはずです。Projected boostのMin&Max値MultiIndexイテレータ

私は、その範囲内で最大/最小値が間違っていると仮定して、500に強制的に反復しています。私が取る必要があるのは、トップ10のユニーク価格であり、価格が繰り返される場合はその数量を合計します。

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

トップ10の価格を数量で取得しようとしているのと同じです。

resultは、std::lessでソートしても、printf(データの生成にコメントされています)を使用して生成されます。もう1人のホルダーが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

ありがとうございます。不完全なサンプルは残念です。 –