Boost.MultiIndex データ構造内のワイルドカード検索?
-
20-09-2019 - |
質問
データベースへのラウンドトリップを減らしてアプリケーションを最適化しようとしています。その取り組みの一環として、いくつかのテーブルをメモリに移動し、次のように保存しています。 Boost.MultiIndex コンテナ。
このプロセスの副作用として、文字列でワイルドカード マッチングを実行できなくなりました。たとえば、テーブルが MySQL に保存されている場合は、次のようにすることができます。
SELECT * FROM m_table WHERE myString LIKE "foo%"
ただし、現在は myString のキーを持つ Boost.MultiIndex コンテナーを使用しているため、その機能が失われているようです。
明らかに、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_match() を使用して各キーを boost::regex と比較することのようです。
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;
}
もっと良い方法はありますか?
解決
まず、実際に boost::regex を使用する必要はありません。ワイルドカードが十分に単純であれば、独自の単項演算子をロールすることで回避できます。Boost.Regex は、(ヘッダーのみではなく) 実際にリンクする必要があるライブラリの数少ない部分の 1 つであることに注意してください。
建物全体を歩くという問題に関しては、申し訳ありませんが、ここでできることはあまりありません...事前に検索内容がわからない場合。
探しているパラメーターが事前にわかっている場合は、専用のコンパレーター/ハッシュ (たとえば、最初のパラメーターのみを考慮するビュー) を使用して、このタスクを実行するのに適したマルチインデックス コンテナーの特別なビューを作成できます。 3文字)。
さらに詳しい情報をご希望の場合は、使用したいワイルドカードの種類と状況に関する詳細情報を提供してください。
他のヒント
特定のケースでは、 lower_bound("foo") を実行し、一致しないものにヒットするかコンテナの最後に到達するまで、一致するものを探して前に進みます。ただし、この検索を行う一般的な方法はないと思います。