namazu-ml(avocado)


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Perl version search program (Re: Tawagoto?)



古川です。

>> On Wed, 4 Mar 1998 19:44:18 +0900, Satoru Takabayashi <ccsatoru@xxxxxxxxxxxxxxxxxx> said:
  > …ところが

  > /^html)"/: unmatched () in regexp at
  > /home/ccsatoru/tmp/uu/pnamazu.cgi line 146, <INDEX> chunk 6.
  > のようなエラーが出てしまいました。ということで

なるほど。私のところでは、極力、記号を排除して運用しているので、気がつ
きませんでした。ありがとうございます。

  >  sub readindexindex{
  >      # NMZ.ii の N 番目の語を NMZ.i から読んで返す
 
  >      my($N) = @_;
  >      my($BUF);
  >      seek(INDEX, &indexpointer(*INDEXINDEX, $N), 0);
  >      $BUF = <INDEX>;
  >      chop($BUF);
  > +    $BUF = quotemeta($BUF);
  >      $BUF;
  >  }

私は実は perl4 までの機能しか使えない人間なので、quotemeta というのを
初めて知りました。

私のところの perl だけかもしれませんが、これだと、日本語のコードが化け
てしまいます。

    s/[\x00-\x7f]+/quotemeta($&)/ge;

のようにするといいようなのですが。あと、ここで quotemeta を使うと、のち
のち困るようです。


  > と修正しました。これは私もよく失敗するミスです :-)。

これ以外にも、小さなバグからとんでもないバグまで、いろいろ見つかりました。

全部まとめて、最後に patch を添付します。

今後も、どんどんバグが見つかるものと推測されますが、よろしくお願いします。



  > C言語版
  >   % time namazu . html >/dev/null 
  
  >   real    0m0.039s
  >   user    0m0.010s
  >   sys     0m0.030s

  > Perl版
  >   % time perl pnamazu.cgi  >/dev/null 
  
  >   real    0m0.188s
  >   user    0m0.140s
  >   sys     0m0.040s

  > のようになりました。ほぼ予想通りという感じがします。まずますですね。

C 版が「中小規模向け」ならば、perl 版は「小規模向け」の機能限定版という
ことで…

-- 

                                        ヤマハ(株)ピアノプレーヤ設計課
                                                              古川 令
                                             furukawa@xxxxxxxxxxxxxxxx
------------------------------ ここから ------------------------------
*** pnamazu.cgi.orig	Wed Mar  4 17:08:47 1998
--- pnamazu.cgi	Wed Mar  4 20:57:32 1998
***************
*** 107,124 ****
      $L = &indexpointer(*HASH, $X);
  
      if ($ForwardMatch){
!         my($N);
          while ($R >= $L){
              $X = int(($L + $R) / 2);
!             if (&readindexindex($X) =~ /^$KEY/){
                  for ($X = $RETX - 1;
!                      $X >= $L && &readindexindex($X) =~ /^$KEY/;
                       $X--){
                      $N += &readindexscore($X, $AND, *ORIG, *SCORE);
                  }
  
                  for ($X = $RETX + 1;
!                      $X <= $R && &readindexindex($X) =~ /^$KEY/;
                       $X++){
                      $N += &readindexscore($X, $AND, *ORIG, *SCORE);
                  }
--- 107,129 ----
      $L = &indexpointer(*HASH, $X);
  
      if ($ForwardMatch){
!         my($N, $PAT);
!         $PAT = $KEY;
!         $PAT =~ s/[\x00-\x7f]+/quotemeta($&)/ge;
          while ($R >= $L){
              $X = int(($L + $R) / 2);
! 
!             $BUF =  &readindexindex($X);
!             if ($BUF =~ /^$PAT/){
!                 $N += &readindexscore($X, $AND, *ORIG, *SCORE);
                  for ($X = $RETX - 1;
!                      $X >= $L && &readindexindex($X) =~ /^$PAT/;
                       $X--){
                      $N += &readindexscore($X, $AND, *ORIG, *SCORE);
                  }
  
                  for ($X = $RETX + 1;
!                      $X <= $R && &readindexindex($X) =~ /^$PAT/;
                       $X++){
                      $N += &readindexscore($X, $AND, *ORIG, *SCORE);
                  }
***************
*** 133,140 ****
          $HIT{"$KEY*"} = $N;
          return ("$KEY*", '');
      }else{
!         my($LEN, $BUF);
!         my($MAXX, $MAXLEN, $MAXBUF);
          $MAXX = -1;
          while ($R >= $L){
              $X = int(($L + $R) / 2);
--- 138,145 ----
          $HIT{"$KEY*"} = $N;
          return ("$KEY*", '');
      }else{
!         my($LEN, $BUF, $PAT);
!         my($MAXX, $MAXLEN, $MAXBUF, $MAXPAT);
          $MAXX = -1;
          while ($R >= $L){
              $X = int(($L + $R) / 2);
***************
*** 143,157 ****
              if ($KEY eq $BUF){
                  $HIT{$KEY} = &readindexscore($X, $AND, *ORIG, *SCORE);
                  return ($KEY, '');
!             }elsif ($KEY =~ /^$BUF/){
!                 # kakasi を呼ばないので、複合語の検索のため
!                 # 最長一致で keyword と index を比較し、
  
!                 $LEN = length($BUF);
!                 if ($MAXLEN < $LEN){
!                     $MAXLEN = $LEN;
!                     $MAXBUF = $BUF;
!                     $MAXX = $X;
                  }
              }
              if (&unsignedcmp($KEY, $BUF) < 0){
--- 148,167 ----
              if ($KEY eq $BUF){
                  $HIT{$KEY} = &readindexscore($X, $AND, *ORIG, *SCORE);
                  return ($KEY, '');
!             }else{
!                 $PAT = $BUF;
!                 $PAT =~ s/[\x00-\x7f]+/quotemeta($&)/ge;
!                 if ($KEY =~ /^$PAT/){
!                     # kakasi を呼ばないので、複合語の検索のため
!                     # 最長一致で keyword と index を比較し、
  
!                     $LEN = length($BUF);
!                     if ($MAXLEN < $LEN){
!                         $MAXLEN = $LEN;
!                         $MAXBUF = $BUF;
!                         $MAXPAT = $PAT;
!                         $MAXX = $X;
!                     }
                  }
              }
              if (&unsignedcmp($KEY, $BUF) < 0){
***************
*** 160,169 ****
                  $L = $X + 1;
              }
          }
!         # keyword の残りは次の語として親ルーチンに返す
!         $KEY =~ s/^$MAXBUF//;
!         $HIT{$MAXBUF} = &readindexscore($MAXX, $AND, *ORIG, *SCORE);
!         return($MAXBUF, $KEY);
      }
  }
  
--- 170,182 ----
                  $L = $X + 1;
              }
          }
!         if ($MAXX >= 0){
!             # keyword の残りは次の語として親ルーチンに返す
!             $KEY =~ s/^$MAXPAT//;
!             $HIT{$MAXBUF} = &readindexscore($MAXX, $AND, *ORIG, *SCORE);
!             return($MAXBUF, $KEY);
!         }
!         return($KEY, '');
      }
  }
  
------------------------------ ここまで ------------------------------