[groonga-dev,03187] grn_patの有効なノードの確認方法

Back to archive index

Kouhei Sutou kou****@clear*****
2015年 4月 23日 (木) 12:18:44 JST


須藤です。

森さん、grn_patでの有効なノードの確認方法について教えてくだ
さい。

知りたいことは次の2つです。

  * 有効な子ノードが親ノードのcheckと同じケースはありえるの
    か(実際にあるんで、それが意図したものなのかを知りたい)

  * 有効な子ノードのcheckが0のケースはありえるのか
    (こっちも実際にあるんで、それが意図したものなのかを知り
    たい)

詳細は次の通りです。

森さんに直してもらった_grn_pat_del()の問題の再現に使ったデー
タでは、grn_p(ctx, pat)(patの中身を読みやすい形で表示する関
数)が期待通りに動かないことがわかりました。具体的には

  1. grn_pat_add("2")
  2. grn_pat_add("1")
  3. grn_pat_add("3")

とした状態で"3"のノードの中身を表示しません。実際の表示は次
のようになっています。

#<table:pat names key:ShortText value:(nil) size:3 columns:[] default_tokenizer:(nil) normalizer:(nil) keys:["1", "2", "3"] subrec:none nodes:{
2("1"){0,6,0}[00110001]
  L:2
  R:1("2"){0,7,0}[00110010]
    L:1
    R:3
}>

解説すると、

--
2("1"){0,6,0}[00110001]
  L:2
  R:1("2"){0,7,0}[00110010]
    L:1
    R:3
--

のところがpatの中身です。
「L:」が付いているのはpat_node::lrの[0]の方で
「R:」が付いているのはpat_node::lrの[1]の方です。
一番上の「L:」も「R:」も付いていないやつは最初のノードです。

「L:」、「R:」の右側にある数字はPAT_AT()したときに使った
grn_idです。

キーがあると判断したところでは

  (#{キー}){#{checkの中身}}[#{キーのバイト列}]

というフォーマットでpat_nodeの中身を表示しています。

なお、

  {#{checkの中身}}

は

  {#{nth_byte},#{nth_bit},#{terminated}}

というように16ビットに詰め込んだ情報を分割して表示しています。

で、これを

--
2("1"){0,6,0}[00110001]
  L:2
  R:1("2"){0,7,0}[00110010]
    L:1
    R:3 ←が「R:3("3"){...}[...]」となってほしい!!
--

というようにしたいです。

grn_p(ctx, pat)の実装(grn_pat_inspect_node())では、

  https://github.com/groonga/groonga/blob/master/lib/pat.c#L50-L51

の

typedef struct {
  grn_id lr[2];
  /*
  ...
  The both available nodes has larger check value rather
  than the current node.
  ...
  */
  ...;
} pat_node;

というコメントを信じてcheckの値を使って

  https://github.com/groonga/groonga/blob/master/lib/pat.c#L2370

  if (c > check) {

というように、そのノードのキーを表示するかどうかを判断してい
ます。

が、この条件だと「"3"」のノードを有効なノードと判断できませ
ん。

というのは、このケースでは↓というように「"2"」のノードと
「"3"」のノードのcheckが同じ値(14)になっているからです。

--
2("1"){0,6,0}[00110001]
  L:2
  R:1("2"){0,7,0}[00110010]
    L:1
    R:3("3"){0,7,0}[00110011]
--

これは妥当なケース(意図した動作)なんでしょうか?(質問1)

妥当なケースならgrn_pat_inspect_node()でもこのケースに対応し
ようと思っています。

で、もうひとつのケースは

  1. grn_pat_add("2")
  2. grn_pat_add("1")
  3. grn_pat_add("3")

の後に

  4. grn_pat_del("2")

をした状態のケースです。

この状態ではpatの中身は次のようになっています。

--
2("1"){0,6,0}[00110001]
  L:2
  R:3("3"){0,0,0}[00110011]
--

気になるところは「"3"」のノードのcheckが0なことです。

これは妥当なケース(意図した動作)なんでしょうか?(質問2)

妥当なケースならgrn_pat_inspect_node()でもこのケースに対応し
ようと思っています。

ちなみに、

  1. grn_pat_add("1")
  2. grn_pat_add("3")

とすると次のようになり、checkは14になります。

--
2("1"){0,6,0}[00110001]
  L:2
  R:1("3"){0,7,0}[00110011]
    L:0
    R:1("3"){0,7,0}[00110011]
--



-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/>

Groongaベースの全文検索システムを総合サポート:
  http://groonga.org/ja/support/
パッチ採用 - プログラミングが楽しい人向けの採用プロセス:
  http://www.clear-code.com/recruitment/
コードリーダー育成支援 - 自然とリーダブルコードを書くチームへ:
  http://www.clear-code.com/services/code-reader/




groonga-dev メーリングリストの案内
Back to archive index