c++ 是否可以将参数对/元组作为Boost多索引容器键索引

jv4diomz  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(186)

我有这样的要求,数据应该使用多个关键接口访问。我发现这是可能的助推器多索引容器。
但是这里对于每个键索引接口,只有一个成员可以被传递/使用作为键来访问它。对于我的要求,键可以是std::pair〈member 1,member 2〉,甚至是tuple,如std::tuple〈member 1,member 2,memebr 3〉。
我的问题是,有没有可能把键作为boost多索引容器的pair/tuple参数,或者在c++中有没有其他的过程可以达到这个要求。
示例,我尝试在这里给出.

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/member.hpp>
#include <string>
#include <iostream>
//#include <boost/multi_index/identity.hpp>

using namespace boost::multi_index;

//tags
struct NR_PCI {};
struct NR_FREQ_REF {};
struct NR_MOID {};

struct nr_cell_relation
{
    uint16_t id;
    uint16_t nr_freq_ref;
    uint16_t pci;
    uint64_t nrCellIdentity;
};

typedef multi_index_container<
nr_cell_relation,
    indexed_by<
    sequenced<>,
    //    ordered_unique<identity<nr_cell_relation> >,
    ordered_unique< tag<NR_PCI>, member< nr_cell_relation, uint16_t, &nr_cell_relation::pci > >,
    ordered_unique< tag<NR_MOID>, member< nr_cell_relation, uint16_t, &nr_cell_relation::id > > > > nr_anr_nrt_t;

nr_anr_nrt_t nr_anr_nrt;

bool pci_entry_exits(uint16_t pci)
{
    auto &pci_index = nr_anr_nrt.get<NR_PCI>();
    auto itr = pci_index.find(pci);
    if (itr != pci_index.end())
    {
        std::cout<<"PCI MAP Entry Exist: PCI"<<itr->pci<<std::endl;
        return true;
    }
    std::cout<<"PCI MAP Entry Not Exist: PCI"<<pci<<std::endl;
    return false;
}

bool mo_id_entry_exits(uint16_t id)
{
    auto &pci_index = nr_anr_nrt.get<NR_MOID>();
    auto itr = pci_index.find(id);
    if (itr != pci_index.end())
    {
        std::cout<<"MOID Entry Exist: MOID:"<<itr->id<<":PCI:"<<itr->pci<<std::endl;
        return true;
    }
    std::cout<<"MOID Entry Not Exist: MOID"<<id<<std::endl;
    return false;
}

int main()
{

    if (!pci_entry_exits(304))
    {
        nr_anr_nrt.push_back({1, 2, 304, 1234566});
    }
    if (!pci_entry_exits(301))
    {
        nr_anr_nrt.push_back({4, 1, 301, 1234567});
    }
    if (!pci_entry_exits(303))
    {
        nr_anr_nrt.push_back({2, 2, 303, 1234569});
    }
    if (!pci_entry_exits(302))
    {
        nr_anr_nrt.push_back({3, 1, 302, 1234568});
    }

    if (!pci_entry_exits(302))
    {
        nr_anr_nrt.push_back({5, 1, 302, 1234568});
    }

    if (mo_id_entry_exits(4))
    {
        nr_anr_nrt.push_back({4, 1, 302, 1234568});
    }

    std::cout<<"NRT DUMP with PCI KEY:"<<std::endl;
    auto it = nr_anr_nrt.get<NR_PCI>().begin();
    for (; it != nr_anr_nrt.get<NR_PCI>().end(); ++it)
    {
        std::cout << "MOID:"<<it->id<<"\tFreq_Ref:"<<it->nr_freq_ref<<"\tNR_PCI:"<<it->pci<<std::endl;
    }

    std::cout<<"NRT DUMP with MOID KEY:"<<std::endl;
    auto itr = nr_anr_nrt.get<NR_MOID>().begin();
    for (; itr != nr_anr_nrt.get<NR_MOID>().end(); ++itr)
    {
        std::cout << "MOID:"<<itr->id<<"\tFreq_Ref:"<<itr->nr_freq_ref<<"\tNR_PCI:"<<itr->pci<<std::endl;
    }

    std::cout<<"NRT DUMP ORDER OF INSERTION:"<<std::endl;
    auto it_r = nr_anr_nrt.begin();
    for (; it_r != nr_anr_nrt.end(); ++it_r)
    {
        std::cout << "MOID:"<<it_r->id<<"\tFreq_Ref:"<<it_r->nr_freq_ref<<"\tNR_PCI:"<<it_r->pci<<std::endl;
    }
}

 `

sample example I have tried, expecting is there any container in c++ which can be accessed with multiple keys as interfaces to access the data.

need help to insertion/deletion or search/find elements with composite keys are needed for me

  composite_key<
      nr_cell_relation,
      member< nr_cell_relation, uint16_t, &nr_cell_relation::nr_freq_ref>,
      member< nr_cell_relation, uint16_t, &nr_cell_relation::pci >
      >
      >,


#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/member.hpp>
#include <string>
#include <iostream>
//#include <boost/multi_index/identity.hpp>

using namespace boost::multi_index;

//tags
struct NR_PCI {};
struct NR_FREQ_REF {};
struct NR_MOID {};

struct nr_cell_relation
{
    uint16_t id;
    uint16_t nr_freq_ref;
    uint16_t pci;
    uint64_t nrCellIdentity;
};

typedef multi_index_container<
nr_cell_relation,
    indexed_by<
    sequenced<>,
    //    ordered_unique<identity<nr_cell_relation> >,
    ordered_unique< tag<NR_PCI>, member< nr_cell_relation, uint16_t, &nr_cell_relation::pci > >,
    ordered_unique< tag<NR_MOID>, member< nr_cell_relation, uint16_t, &nr_cell_relation::id > > > > nr_anr_nrt_t;

nr_anr_nrt_t nr_anr_nrt;

bool pci_entry_exits(uint16_t pci)
{
    auto &pci_index = nr_anr_nrt.get<NR_PCI>();
    auto itr = pci_index.find(pci);
    if (itr != pci_index.end())
    {
        std::cout<<"PCI MAP Entry Exist: PCI"<<itr->pci<<std::endl;
        return true;
    }
    std::cout<<"PCI MAP Entry Not Exist: PCI"<<pci<<std::endl;
    return false;
}

bool mo_id_entry_exits(uint16_t id)
{
    auto &pci_index = nr_anr_nrt.get<NR_MOID>();
    auto itr = pci_index.find(id);
    if (itr != pci_index.end())
    {
        std::cout<<"MOID Entry Exist: MOID:"<<itr->id<<":PCI:"<<itr->pci<<std::endl;
        return true;
    }
    std::cout<<"MOID Entry Not Exist: MOID"<<id<<std::endl;
    return false;
}

int main()
{

    if (!pci_entry_exits(304))
    {
        nr_anr_nrt.push_back({1, 2, 304, 1234566});
    }
    if (!pci_entry_exits(301))
    {
        nr_anr_nrt.push_back({4, 1, 301, 1234567});
    }
    if (!pci_entry_exits(303))
    {
        nr_anr_nrt.push_back({2, 2, 303, 1234569});
    }
    if (!pci_entry_exits(302))
    {
        nr_anr_nrt.push_back({3, 1, 302, 1234568});
    }

    if (!pci_entry_exits(302))
    {
        nr_anr_nrt.push_back({5, 1, 302, 1234568});
    }

    if (mo_id_entry_exits(4))
    {
        nr_anr_nrt.push_back({4, 1, 302, 1234568});
    }

    std::cout<<"NRT DUMP with PCI KEY:"<<std::endl;
    auto it = nr_anr_nrt.get<NR_PCI>().begin();
    for (; it != nr_anr_nrt.get<NR_PCI>().end(); ++it)
    {
        std::cout << "MOID:"<<it->id<<"\tFreq_Ref:"<<it->nr_freq_ref<<"\tNR_PCI:"<<it->pci<<std::endl;
    }

    std::cout<<"NRT DUMP with MOID KEY:"<<std::endl;
    auto itr = nr_anr_nrt.get<NR_MOID>().begin();
    for (; itr != nr_anr_nrt.get<NR_MOID>().end(); ++itr)
    {
        std::cout << "MOID:"<<itr->id<<"\tFreq_Ref:"<<itr->nr_freq_ref<<"\tNR_PCI:"<<itr->pci<<std::endl;
    }

    std::cout<<"NRT DUMP ORDER OF INSERTION:"<<std::endl;
    auto it_r = nr_anr_nrt.begin();
    for (; it_r != nr_anr_nrt.end(); ++it_r)
    {
        std::cout << "MOID:"<<it_r->id<<"\tFreq_Ref:"<<it_r->nr_freq_ref<<"\tNR_PCI:"<<it_r->pci<<std::endl;
    }
}
brgchamk

brgchamk1#

是的。你正在寻找组合键。在你的例子中,例如。

bmi::ordered_unique<bmi::composite_key<
    bmi::key<&nr_cell_relation::id>, bmi::key<&nr_cell_relation::nr_freq_ref>,
    bmi::key<&nr_cell_relation::pci>,
    bmi::key<&nr_cell_relation::nrCellIdentity>>>,

在有序索引的情况下,您甚至可以使用部分键进行查询(从左到右最重要,因此按字典顺序)。
下面是一个相当做作的演示:

    • 一个
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/key.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>

namespace Lib {
    struct Relation {
        uint16_t id;
        uint16_t nr_freq_ref;
        uint16_t pci;
        uint64_t nrCellIdentity;
    };

    struct NR_PCI;
    struct NR_MOID;

    namespace detail {
        using namespace boost::multi_index;

        using nr_anr_nrt_t = multi_index_container<                 //
            Relation,                                               //
            indexed_by<                                             //
                sequenced<>,                                        //
                ordered_unique<composite_key<                       //
                    Relation,                                       //
                    key<&Relation::nr_freq_ref>,                    //
                    key<&Relation::id>,                             //
                    key<&Relation::pci>,                            //
                    key<&Relation::nrCellIdentity>                  //
                    >>,                                             //
                ordered_unique<tag<NR_PCI>, key<&Relation::pci>>,   //
                ordered_unique<tag<NR_MOID>, key<&Relation::id>>>>; //
    } // namespace detail

    using detail::nr_anr_nrt_t;
} // namespace Lib

#include <boost/pfr.hpp> // only for debug output
#include <boost/range/iterator_range.hpp>
#include <iostream>
BOOST_PFR_FUNCTIONS_FOR(Lib::Relation)

void dump(auto& os, auto const& table) {
    for (auto& rec : boost::make_iterator_range(table))
        os << " * " << rec << "\n";
}

int main() {
    using namespace Lib;

    std::cout << "(id, freqref, pci, nrcellid)\n";

    nr_anr_nrt_t nr_anr_nrt{
        {4, 9990, 11, 33},
        {1, 3330, 44, 99},
        {3, 5550, 22, 77},
        {2, 5550, 33, 55},
    };

    dump(std::cout << "sequenced:\n", nr_anr_nrt);
    dump(std::cout << "pci:\n", nr_anr_nrt.get<NR_PCI>());
    dump(std::cout << "moid:\n", nr_anr_nrt.get<NR_MOID>());

    auto& composite = nr_anr_nrt.get<1>(); // untagged index by integer id

    using boost::make_tuple;
    dump(std::cout << "composite freqref 3330:\n",
         composite.equal_range(3330));
    dump(std::cout << "composite freqref 5550:\n",
         composite.equal_range(5550));
    dump(std::cout << "composite (5550, 2):\n",
         composite.equal_range(make_tuple(5550, 2)));
    dump(std::cout << "composite (5550, 3):\n",
         composite.equal_range(make_tuple(5550, 3)));

    auto f = composite.lower_bound(1);
    auto l = composite.upper_bound(make_tuple(5550, 2));
    dump(std::cout << "composite range:\n", std::pair(f, l));
}

图纸

(id, freqref, pci, nrcellid)
sequenced:
 * {4, 9990, 11, 33}
 * {1, 3330, 44, 99}
 * {3, 5550, 22, 77}
 * {2, 5550, 33, 55}
pci:
 * {4, 9990, 11, 33}
 * {3, 5550, 22, 77}
 * {2, 5550, 33, 55}
 * {1, 3330, 44, 99}
moid:
 * {1, 3330, 44, 99}
 * {2, 5550, 33, 55}
 * {3, 5550, 22, 77}
 * {4, 9990, 11, 33}
composite freqref 3330:
 * {1, 3330, 44, 99}
composite freqref 5550:
 * {2, 5550, 33, 55}
 * {3, 5550, 22, 77}
composite (5550, 2):
 * {2, 5550, 33, 55}
composite (5550, 3):
 * {3, 5550, 22, 77}
composite range:
 * {1, 3330, 44, 99}
 * {2, 5550, 33, 55}

相关问题