Я пробовал несколько решений, используя библиотеку interprocess boost с картой, а теперь multi_index_container в общей памяти. С multi_index_container существует ли какой-либо способ, кроме как итерации над значениями, возвращаемыми с equal_range. Я надеялся получить подмножество результатов из моего индекса non_unique (название станции, например ST0012345), а затем найти/получить фактический тип измерения, который мне нужен (например, температура).
Мне нужно получить уникальное значение pointID для точки измерения (например, ST0012345SMD10000456.VoltsA = pointID - 45789), чтобы вставить измеренное значение в Data Historian. Мне понравилась идея multi_index_container, так как наши полезные сообщения содержат от 100 до 200 измерений для одной станции в массиве, поэтому я подумал, что могу сделать один вызов в контейнер общей памяти, который будет содержать 500, 000+ элементов, а затем искать каждое измерение точку из гораздо меньшего списка, используя длинное уникальное имя строки.
Кажется, из чтения, которое я сделал, я могу только выполнить итерацию по меньшему списку, возвращенному из multi_index_container, а не к get/find.
Если это так, мне лучше оставить свое исходное решение для карты памяти с общей памятью (которое у меня работает), которое, как я сказал, содержит 500, 000+ элементов длинных строк, чтобы соответствовать для получения точечного идентификатора, требуемого нашими данными историк. Существует высокая скорость передачи данных с 200 пунктами, обрабатываемыми в секунду (я обнаружил, что мой поиск по карте данных может достигать 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;
}
Подумайте об использовании составного ключа в названии станции и температуре (какой индекс вы можете использовать для поиска по имени станции в одиночку или в операциях, связанных с двумя ключами).