boost :: multi_index_container - равные значения

0

Я пробовал несколько решений, используя библиотеку 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;

}

  • 0
    Итак, в чем вопрос?
  • 0
    Значения, возвращаемые равным_ранджем, есть ли способ затем найти или получить эти значения, используя уникальный ключ, или я могу перебирать только значения?
Показать ещё 2 комментария
Теги:
boost-multi-index
boost

1 ответ

0

Подумайте об использовании составного ключа в названии станции и температуре (какой индекс вы можете использовать для поиска по имени станции в одиночку или в операциях, связанных с двумя ключами).

  • 0
    Привет Хоакин, этот поиск должен обрабатывать 200 запросов в секунду. Для 500 000 записей я бы лучше придерживался простой карты совместно используемой памяти <string, int> и находил точную точку измерения при каждом поиске, или продолжал бы идти по многоиндексному пути, который использует составной ключ, как вы предлагаете, или ключ non_unique. который извлекает значения диапазона, которые я затем перебираю, чтобы найти точную точку измерения. Также как другое решение, возможно ли построить много карт в совместно используемой памяти, например: plot.construct <measure_map_type> ("map1"), сегмент.construct <measure_map_type> ("map2"), .... (mapN)?
  • 0
    Что ж, я бы сказал, что вам нужно зарегистрироваться, чтобы узнать, какой ваш лучший вариант. Однако запрос 500-элементного контейнера менее чем за 5 мс не выглядит для меня невероятно трудным (я провел простой тест с набором из 700 kints на Intel Core i5-2520M при 2,50 ГГц, а запросы заняли около 7 человек) ,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню