Поиск по шаблону внутри структуры данных Boost.MultiIndex? - PullRequest
2 голосов
/ 06 октября 2009

Я пытаюсь оптимизировать свое приложение, уменьшая количество обращений к моей базе данных. В рамках этих усилий я перенес некоторые таблицы в память, сохранив их в виде Boost.MultiIndex контейнеров.

В качестве побочного эффекта этого процесса я потерял способность сопоставлять символы подстановки в моих строках. Например, когда таблица хранилась в MySQL, я мог сделать это:

SELECT * FROM m_table WHERE myString LIKE "foo%"

Однако, поскольку я сейчас использую контейнер Boost.MultiIndex с ключом myString, похоже, я потерял эту способность.

Очевидно, я могу использовать функцию equal_range (), чтобы найти все записи, которые точно соответствуют определенной строке:

std::pair< typename T::template index<by_name>::type::iterator,
           typename T::template index<by_name>::type::iterator > p
  = m_table.get<by_name>().equal_range(myString);

while (p.first != p.second )
{
  // do something with the EXACT matching entry
  ++p.first;
}

Но, похоже, что единственный способ сделать подстановочный знак - это пройтись по всей структуре и сравнить каждый ключ с boost :: regex с boost :: regex_match ().

std::pair< typename T::template index<by_name>::type::iterator,
           typename T::template index<by_name>::type::iterator > p
  = std::make_pair(m_table.get<by_name>().begin(),m_table.get<by_name>().end());

while (p.first != p.second )
{
  boost::regex e(myRegex);
  if ( boost::regex_match(p.first->myString, e ) )
  {
     // Do something with the REGEX matching entry
  }
  ++p.first;
}

Есть ли лучший способ?

Ответы [ 2 ]

1 голос
/ 06 октября 2009

Ну, во-первых, вам на самом деле не нужно использовать boost :: regex, если подстановочный знак достаточно прост, вы можете уйти, бросив свой собственный унарный оператор. Я хотел бы отметить, что Boost.Regex является одной из немногих частей библиотеки, которая на самом деле должна быть связана (не только с заголовками).

Что касается проблемы обхода всей конструкции, я прошу прощения, но мало что можно сделать здесь ... если вы не знаете поисков заранее.

Если вы знаете параметры, которые вы будете искать заранее, то вы можете создать специальное представление контейнера Multi-Index, подходящее для выполнения этой задачи, с помощью специального компаратора / хеша (например, тот, который принимает только аккаунт первые 3 символа).

Если вы надеялись на большее, предоставьте больше информации о типе подстановочных знаков, которые вы хотите использовать, и обстоятельствах.

1 голос
/ 06 октября 2009

В вашем конкретном случае вы можете сделать lower_bound ("foo") и затем идти вперед в поисках совпадений, пока не достигнете чего-то, что не соответствует или не достигнет конца контейнера. Я не думаю, что есть общий способ сделать этот поиск.

...