2

データベースへの往復を減らして、アプリケーションを最適化しようとしています。その取り組みの一環として、いくつかのテーブルをメモリに移動し、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;
}

より良い方法はありますか?

4

2 に答える 2

1

特定のケースでは、 lower_bound("foo") を実行してから、一致しないものにヒットするか、コンテナーの最後に到達するまで、一致を探して前方に歩きます。ただし、この検索を行う一般的な方法はないと思います。

于 2009-10-06T17:13:59.027 に答える
1

最初に実際に boost::regex を使用する必要はありません。ワイルドカードが十分に単純な場合は、独自の単項演算子をローリングすることで回避できます。Boost.Regex は、実際にリンクする必要があるライブラリの数少ない部分の 1 つであることに注意してください (ヘッダーのみではありません)。

構造全体を歩くという問題に関しては、申し訳ありませんが、ここでできることはあまりありません...事前に検索を知らない場合。

探しているパラメータが事前にわかっている場合は、専用のコンパレータ/ハッシャー (たとえば、最初の3文字)。

それ以上を希望する場合は、使用したいワイルドカードの種類と状況に関する詳細情報を提供してください。

于 2009-10-06T17:15:17.513 に答える