Namazu-users-ja(旧)


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

インデックスの分割 (Re: インデックスのマージ)



古川です。

From: Osamu Okano <osamu2001@xxxxxxxxxxxx>
Subject: [namazu-users-ja] Re: pnamazu-2000.10.07 (インデックスのマージ)
Date: Tue, 10 Oct 2000 23:21:36 +0900

osamu2001> かなり前の話ですが
osamu2001> インデックスのマージツールを作る話
osamu2001> があったと思うのですが

かなり前の話ですが
インデックスの分割ツールを作る話

…は無かったと思いますが、作ってみました。


Usage: nmzseparate.pl pattern src dst1 dst2

pattern によって、dst1 に入れる条件を指定します。pattern を評価する
時点では、

    $r      NMZ.r
    $t      NMZ.t
    $date   NMZ.field.date
    $size   NMZ.field.size
      ...
    $XXX    NMZ.field.XXX

という変数がセットされています。

(例) インデックス 'all' を 'sun' と 'others' に分割する。
    sun には、日曜日に作られたファイル情報を入れる。

        % nmzseparate.pl '$date =~ /Sun/' all sun others

(注意 1)
dst1 と dst2 が同じディレクトリを指していると、(特に警告なども出す
ことなく) 誤動作します


(注意 2)
ファイルをたくさん開くので、私の環境では

        % unlimit descriptors

としないと動かなかったです。


-- 
Rei FURUKAWA 
furukawa@xxxxxxxxxxxx
#! /usr/local/bin/perl5 -w

use strict;

push(@INC, "/usr/local/share/namazu/pl");
require 'nmzidx.pl';

print("Usage: nmzmerge.pl pattern src dst1 dst2\n"), exit if @ARGV != 4;

&nmzseparate(@ARGV);

sub nmzseparate{
    my ($pattern, $dir0, $dir1, $dir2) = @_;

    my $src = new nmzidx($dir0, 'r');

    my @dst = (new nmzidx($dir2, 'w'), new nmzidx($dir1, 'w'));

    my @separate = ();
    {
        my $src_file = $src->open_flist;
        my @field = keys %{$src_file->{'field'}};

        my @dst_file = map {$_->open_flist} @dst;

        my $evalstr = '';
        $evalstr .= "my \$r = \$list{'r'};\n";
        $evalstr .= "my \$t = \$list{'t'};\n";

        for my $field (@field){
            my $tmp = $field;
            $tmp =~ s/[^A-Za-z]+//g;
            $evalstr .= "my \$$tmp = \$list{'field'}{'$field'};\n";
            for my $dst (@dst){
                $dst->{'flist'}->{'field'}->open($dst, $field) unless defined $dst->{'flist'}->{'field'}->{$field};
            }
        }
        
        $evalstr .= "\$ret = ($pattern);\n";

        my @size = (0, 0);
        my %list;
        my $ndx = 0;
        my $size = $src_file->{'size'};
        while (defined $src_file->read(\%list)){
            my $ret;
            eval($evalstr);
            my $separate = $ret? 1: 0;
            push(@separate, {'separate' => $separate,
                             'no' => $size[$separate]});
            ++$size[$separate];
            $dst[$separate]->{'flist'}->write(\%list);
            print "$ndx/$size\n" unless ++$ndx % 100;
        }
        $src_file->close;
        map {$_->close} @dst_file;
    }
    {
        my $src_word = $src->open_word;

        my @dst_word = map {$_->open_word} @dst;

        my $ndx = 0;
        my $size = $src_word->{'size'};

        my ($word, %list);
        while (defined $src_word->read(\$word, \%list)){
            my(%list1, %list2);
            my @refs = (\%list2, \%list1);

            for my $key (keys %list){
                my $separate = $separate[$key]->{'separate'};
                my $no = $separate[$key]->{'no'};
                $refs[$separate]->{$no} = $list{$key};
            }

            for my $key (0, 1){
                if (keys %{$refs[$key]}){
                    $dst_word[$key]->write($word, $refs[$key]);
                }
            }
            print "$ndx/$size $word\n" unless ++$ndx % 100;
        }
        $src_word->close;
        map {$_->close} @dst_word;
    }
    {
        my $src_phrase = $src->open_phrase;
        my @dst_phrase = map {$_->open_phrase} @dst;

        for (my $ndx = 0; $ndx < 0x10000; $ndx++){
            my (@list, @list1, @list2);
            my @refs = (\@list2, \@list1);

            $src_phrase->read(\@list);
            for my $key (@list){
                my $separate = $separate[$key]->{'separate'};
                my $no = $separate[$key]->{'no'};
                push(@{$refs[$separate]}, $no);
            }
            for my $ndx (0, 1){
                $dst_phrase[$ndx]->write($refs[$ndx]);
            }
            printf("phrase %04X\n", $ndx) unless $ndx & 0xff;
        }
    }

    for my $dst (@dst){
        $dst->write_status($src);
        if (my $log = $dst->log_open("[Separate]")){
            $log->printf("%-20s %d\n", "Total Files:", $dst->{'flist'}->{'offset'});
            $log->printf("%-20s %d\n", "Total Keywords:", $dst->{'word'}->{'offset'});
            $dst->log_close;
        }
        $dst->replace_db(0);
    }
}