Namazu-devel-ja(旧)


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

negative integer bug



<200008020031.JAA16451@xxxxxxxxxxxxx>の記事において
私は書きました。

>> Cannot compress negative numbers 
>> <http://www.namazu.org/ml/namazu-users-ja/msg00700.html>
>> は最近某所でも問題にされたので、今日はこの問題に取り組んでみようと思っ
>> ていました。

  鵜飼さんの協力を得て原因らしきものが見えてきました。

  write_index_sub などの中で index の merge をする時に、追加分の最初の
docid が既存のデータの最後の docid よりも小さい時に adjust_first_docid 
で negative になってしまう、というのが原因のようです。
  そもそもそうなってしまうこと自体がおかしいのかどうかは良くわからなかっ
たのですが、とりあえずここのロジックを変更して append_record という関
数を新たに導入することで対処してみました。
  make check すると一部 fail するのでまだ問題があるかもしれません。一
応ソースの差分をつけておきますので、どなたか検証してみていただけません
でしょうか。

-- 
野首 貴嗣
E-mail: knok@xxxxxxxxxxxxx (private)
	knok@xxxxxxxxxx (Namazu Project)

Index: scripts/mknmz.in
===================================================================
RCS file: /storage/cvsroot/namazu/scripts/mknmz.in,v
retrieving revision 1.68
diff -c -r1.68 mknmz.in
*** scripts/mknmz.in	2000/07/19 09:09:36	1.68
--- scripts/mknmz.in	2000/08/02 09:15:32
***************
*** 2083,2092 ****
  	    } else {
  		print $fh_tmp_pi pack("N", $ptr);
  		my $record = $PhraseHash{$i};
! 		my $last_docid = get_last_docid($baserecord, 1);
! 		$record = adjust_first_docid($record, $last_docid);
! 		my $n2 = length($record) + $baseleng;
! 		my $data = pack("w", $n2) .  $baserecord . $record;
  		print $fh_tmp_p $data;
  		$ptr += length($data);
  	    }
--- 2083,2091 ----
  	    } else {
  		print $fh_tmp_pi pack("N", $ptr);
  		my $record = $PhraseHash{$i};
! 		my $newrecord = append_record($baserecord, $record, 1);
! 		my $n2 = length($newrecord);
! 		my $data = pack("w", $n2) . $newrecord;
  		print $fh_tmp_p $data;
  		$ptr += length($data);
  	    }
***************
*** 2263,2268 ****
--- 2262,2301 ----
      return $record;
  }
  
+ sub append_record ($$$) {
+     my ($baserecord, $record, $step) = @_;
+     my (@data) = unpack 'w*', $baserecord;
+     my %exdata = ();
+     my $sum = 0;
+     for (my $i = 0; $i < @data; $i += $step) {
+ 	$sum += $data[$i];
+ 	$exdata{$sum} = [$sum];
+ 	if ($step > 1) {
+ 	    push @{$exdata{$sum}}, $data[$i+1];
+ 	}
+     }
+     @data = unpack 'w*', $record;
+     for (my $i = 0; $i < @data; $i += $step) {
+ 	$sum += $data[$i];
+ 	$exdata{$sum} = [$sum];
+ 	if ($step > 1) {
+ 	    push @{$exdata{$sum}}, $data[$i+1];
+ 	}
+     }
+     my (@rdata) = ();
+     my (@skeys) = sort keys %exdata;
+     my $tmp = pop @skeys;
+     push @rdata, @{$exdata{$tmp}};
+     my $cur = $exdata{$tmp}->[0];
+     foreach $tmp (@skeys) {
+ 	$cur += $exdata{$tmp}->[0];
+ 	$exdata{$tmp}->[0] = $cur;
+ 	push @rdata, @{$exdata{$tmp}};
+     }
+     my $rrecord = pack 'w*', @rdata;
+     return $rrecord;
+ }
+ 
  sub write_index_sub () {
      my @words = sort keys(%KeyIndex);
      return 0 if $#words == -1;
***************
*** 2296,2307 ****
  		my $leng = length($record);
  
  		if ($current_word eq $words[$cnt]) {
! 		    my $last_docid = get_last_docid($baserecord, 2);
! 		    $record = adjust_first_docid($record, $last_docid);
! 		    $leng = length($record);  # re-measure
! 		    my $tmp = pack("w", $leng + $baseleng);
  
! 		    my $data_i = "$tmp$baserecord$record";
  		    my $data_w = "$current_word\n";
  		    print $fh_tmp_i $data_i;
  		    print $fh_tmp_w $data_w;
--- 2329,2339 ----
  		my $leng = length($record);
  
  		if ($current_word eq $words[$cnt]) {
! 		    my $newrecord = append_record($baserecord, $record, 2);
! 		    $leng = length($newrecord);  # re-measure
! 		    my $tmp = pack("w", $leng);
  
! 		    my $data_i = "$tmp$newrecord";
  		    my $data_w = "$current_word\n";
  		    print $fh_tmp_i $data_i;
  		    print $fh_tmp_w $data_w;