すべての良い一日。
最近、
MVA (複数値属性)の更新に関連する興味深い問題に遭遇しました。
初期条件:
- sphinx-1.10-beta
- sphinx php api
タスクの一部として、mva属性のオンザフライ更新を実装する必要がありました。 最初から、すべてが十分に単純に思えた
-php APIから
UpdateAttributes()関数を取得し、必要な更新を記述します。 必要なラッパーを書き、テストを開始しました-すべてが正常に動作します。 どういうわけか、こんなに早く起こったことを信じることができませんでした。 彼は、いわば、狂信的でテストを始めました-そして、キャッチはほとんどすぐに追いつきました。
1022を超える値を持つ属性をMVA属性に詰め込もうとすると、クライアントは「
MVA更新時にプールメモリ不足 」というエラーで落ちました。 彼はグーグルを始めました。 この問題は新しいものではなく、可能な解決策として、
sphinx.confのmva_updates_poolパラメーターを変更することをお勧めします。
異なる意味で試してみました。 しかし、そこにどんな価値を置いても、何度もエラーが現れました。
私はかつてCで書いていたので、もう少し深く掘り下げてソースコードを見ることにしました。
友人を招待し(極端なプログラミングの練習をすることにしました)、ビールを飲み、デバッグソースに座っていました。 2時間のデバッグと一定量のビールを飲んだ後、問題が見つかりました。
sphinx.cppには別のチェックがあり、そのパラメーターは構成から変更できないことがわかりました。
int CSphArena::RawAlloc ( int iBytes ) { CheckFreelists (); if ( iBytes<=0 || iBytes>( ( 1 << MAX_BITS ) - (int)sizeof(int) ) ) { return -1; } … }
iBytesは、実際には、MVA属性の下で割り当てられるバイト数です。 そして、条件iBytes>((1 << MAX_BITS)-(int)sizeof(int))は、実際には上からの制限を表します。 簡単に言えば、
MAX_BITS変数
がシフトを担当します。 つまり
IBytesは 、2 ^ MAX_BITS-4(32ビットの場合)と2 ^ MAX_BITS-2(16ビットの場合)と比較されます。 MAX_BITSの値はハードコードされ、12に等しくなります。したがって、MVA属性に詰め込むことができるint番目の値の最大数を計算できます。 intは4バイトかかると考えています。 4092/4 =1023。したがって、制限がありました。
したがって、
MAX_BITSの値を
増やすと、MVA属性の最大長を増やすことができます。 コード内で定数として宣言されているのは残念です。 ソースコードを修正せずに設定で指定することはできません。 つまり この定数を増やして、再構築する必要がありました。
しかし、最も重要なことは、問題が解決されることです。