ブースト プロセス間ライブラリとマップを使用していくつかのソリューションを試し、現在は共有メモリ内の multi_index_container を使用しています。multi_index_container では、equal_range から返された値を反復処理する以外に方法はありますか。non_unique インデックス (ST0012345 などのステーション名) から結果のサブセットを取得し、必要な実際の測定タイプ (温度など) を見つけて取得したいと考えていました。
測定値をデータ ヒストリアンに挿入するには、測定ポイントの一意の pointID 値 (例: ST0012345SMD10000456.VoltsA = pointID - 45789) を取得する必要があります。メッセージペイロードには配列内の1つのステーションの〜100〜200の測定値が含まれているため、multi_index_containerのアイデアが好きだったので、500,000以上のアイテムを含む共有メモリコンテナを1回呼び出して、長い一意の文字列名を使用した、はるかに小さなリスト。
私が行った読み取りから、get/find を実行するのではなく、multi_index_container から返された小さなリストを反復処理することしかできないようです。
その場合、元の共有メモリ マップ ソリューション (私が取り組んでいる) に固執するほうがよいでしょうか。これには、データ ヒストリアンが必要とするポイント ID を取得するために照合する 500,000 個以上の長い文字列が含まれています。1 秒あたり 200 ポイントが処理される高いデータ レートがあります (テスト環境では、データ マップ ルックアップが 1 秒あたり 2000 ルックアップに達することがわかりました)。
また、マップを使用する場合、共有メモリに複数のマップがあることに害はありますか。たとえば、シドニー駅のマップ (~300,000 ポイント)、ニューカッスル駅のマップ (~200,000 ポイント) などです。
以下は、multi_index_container を作成した別のプロセスからアイテムを取得する私のプログラムのコードです。
using namespace boost::interprocess;
using namespace System;
namespace bmi = boost::multi_index;
typedef managed_shared_memory::allocator<char>::type char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>shm_string;
struct tag
{
shm_string name;
shm_string stn;
shm_string mtype;
int id;
tag( const char *name_
, const char_allocator &a
, const char *stn_
, const char_allocator &b
, const char *mtype_
, const char_allocator &d
, int id_)
: name(name_, a),
stn(stn_, b),
mtype(mtype_, d),
id(id_)
{}
};
struct name{};
struct stn{};
struct mtype{};
struct id{};
typedef bmi::multi_index_container<
tag,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<name>, BOOST_MULTI_INDEX_MEMBER(tag,shm_string,name)>,
bmi::ordered_non_unique<
bmi::tag<stn>,BOOST_MULTI_INDEX_MEMBER(tag,shm_string,stn)> >,
managed_shared_memory::allocator<tag>::type
> tag_set;
typedef tag_set::iterator iterator;
int main(array<System::String ^> ^args)
{
try{
managed_shared_memory segment(open_only,"MySharedMemory");
offset_ptr<tag_set> es = segment.find<tag_set>("My MultiIndex Container").first;
char_allocator alloc_inst(segment.get_allocator<char>());
shm_string key_object(alloc_inst);
key_object = "ST0012345SMD10000456";
std::pair<tag_set::index<stn>::type::iterator, tag_set::index<stn>::type::iterator> values = es->get<stn>().equal_range(key_object);
while(values.first != values.second) {
std::cout << values.first->name << " -- " <<" ("<<values.first->stn<<","<<values.first->mtype<<")\n";
++values.first;
}
char_allocator alloc_inst2(segment.get_allocator<char>());
shm_string key_object2(alloc_inst2);
key_object2 = "ST0012345SMD10000456.VoltsA";
///// is there any way something like the following can be done rather than the above iterator ?????
iterator it = values->get<name>(key_object2); <------- ????????????????????????
}
catch(const std::exception &exc){
std::cerr << "Exception caught: " << exc.what();
throw;
}
Sleep(3000);
return 0;
}