Annotation of db/prgsrc/updateRS3.pl, revision 1.3

1.1       roma7       1: #!/usr/bin/perl -w
                      2: 
                      3: =head1 NAME
                      4: 
                      5: updateRS.pl - Скрипт для занесения в таблицы русского поиска базы 
                      6: B<$base> информации о вопросах. Использует DB_File.
                      7: 
                      8: =head1 SYNOPSIS
                      9: 
                     10: updateRS1.pl Questions_per_cicle cicles_number
                     11: 
                     12: updateRS.pl Questions_per_cicle
                     13: 
                     14: updateRS.pl
                     15: 
                     16: 
                     17: =head1 DESCRIPTION
                     18: 
                     19: Скрипт ищет в таблице Questions вопросы с нулевым ProcessedBySearch,
                     20: добавляет информацию в таблицы word2question, nests, nf. Поле 
                     21: ProcessedBySearch устанавливается в 1. Обрабатывает 
                     22: Questions_per_cicle*cicles_number вопросов, сбрасывая 
                     23: информацию в базу каждые Questions_per_cicle вопросов.
                     24: Значения по умолчанию:
                     25: Questions_per_cicle=500;
                     26: cicles_number=1.
                     27: 
                     28: Создание в рабочем каталоге файла RS_pause прерывает работу с сохранением 
                     29: хэшей, это означает, что при следующем запуске скрипт продолжит работу с места
1.2       roma7      30: остановки (обнулится только счётчик обработанных вопросов). 
1.1       roma7      31: Продолжить крайне желательно, потому что у обработанные вопросах 
                     32: уже установлен флаг ProcessedBySearch, но реально информация о них в базу
                     33: ещё не занесена.
                     34: 
                     35: Создание в рабочем каталоге файла RS_stop инициирует процесс завершения 
                     36: работы скрипта, с предварительным занесением информации об обработанных 
                     37: вопросах в базу.
                     38: 
                     39: Оба файла убиваются по окончании работы.
                     40: 
                     41: =head1 AUTHOR
                     42: 
                     43: Роман Семизаров
                     44: 
                     45: 
                     46: =cut
                     47: 
                     48: 
                     49: 
                     50: use locale;
                     51: use DBI;
                     52: use POSIX qw (locale_h);
                     53: use lib "../lib";
                     54: use chgkfiles;
                     55: use dbchgk;
                     56: open (STDERR,">errors");
                     57: my $initime=time;
                     58: open TIME, ">time"; 
                     59: do "common.pl";
                     60: do "chgk.cnf";
                     61: 
                     62: use DB_File;
                     63: 
                     64: 
1.3     ! roma7      65: $stopslovo{'В'}=1;
        !            66: $stopslovo{'С'}=1;
        !            67: $stopslovo{'ИЗ'}=1;
        !            68: $stopslovo{'НА'}=1;
        !            69: $stopslovo{'И'}=1;
        !            70: $stopslovo{'К'}=1;
1.1       roma7      71: 
                     72: 
                     73: $qlimit=shift||500;
                     74: $times=shift||1;
                     75: 
                     76: die "Undefined \$maxwsize! check your chgk.cnf" unless $maxwsize;
                     77: 
                     78: require "check.pl";
                     79: 
                     80: open (STDERR,">$stderr") if $stderr;
                     81: 
                     82: 
                     83: open (UNKNOWN,">$unknown");
                     84: 
                     85: 
                     86:           
                     87: my $nf;
                     88: 
                     89: #open WARN, ">$warnings";
                     90: 
                     91: #%forbidden=checktable('equalto')? getequalto : ();
                     92: 
                     93: 
                     94: if ((uc 'а') ne 'А') {die "!Koi8-r locale not installed!\n"};
                     95: 
                     96: getquestions(QuestionId, Question, Answer, Comments, Authors, Sources,"ProcessedBySearch IS NULL");
                     97: 
                     98: 
                     99: 
                    100: 
                    101: tie %words, 'DB_File', 'words.tmp';
                    102: 
                    103: if (!(scalar keys %words))
                    104: {
                    105:    print "Loading dictionaries\n";
                    106:    die "No dictionaries! Check your chgk.cnf" unless scalar @dictionaries;
                    107:    foreach $d(@dictionaries)
                    108:    {
                    109:      print "Loading $d\n";
                    110:      open (DICT, $d) || print "              Not found\n";
                    111:      while ( <DICT> )
                    112:      {
                    113:        chomp;
                    114:        s/\s*$//;
                    115:                ($aa,$b)=split(/\//);
                    116:                $aa=~tr/ёЁ/еЕ/;
                    117:        $a= uc $aa;
                    118:        $words{$a}.=$b || "!";
                    119:      }
                    120:      close(DICT);
                    121:   }
                    122: }
                    123: 
                    124: die "No dictionaries found! Check your chgk.cnf" unless scalar keys %words;
                    125: 
                    126: 
                    127: 
                    128: print TIME "\t\t".(time-$initime)."\n";
                    129: 
                    130: for my $commonI(1..$times)
                    131: {
                    132: 
                    133: 
                    134: 
                    135: 
                    136: tie %nf, 'DB_File', 'nf.tmp';
                    137: tie %nfnumber, 'DB_File', 'nfnumber.tmp';
                    138: tie %newnf, 'DB_File', 'newnf.tmp';
                    139: tie %neww2k, 'DB_File', 'neww2k.tmp';
                    140: 
                    141: 
                    142: 
                    143: if (!((scalar keys %nf)||(scalar keys %newnf)))
                    144: {
                    145:    print "loading nests\n";
                    146:    %nf=getnests;
                    147:    %nfnumber=getnfnumbers;
                    148: }
                    149:                    
                    150: 
                    151: 
                    152: print "Getting words...\n";
                    153: 
                    154: getquestions(QuestionId, Question, Answer, Comments, Authors, Sources,"ProcessedBySearch IS NULL");
                    155: $sch=0;
                    156: while ((++$sch<=$qlimit) && (($id, @ss) = getrow, $id)) 
                    157:                              # берём по одному вопросу
                    158:                              # и вешаем в массив, индексы которого -- словоформы,
                    159:                              # а значения -- списки вопросов. 
                    160: {
                    161: 
                    162: 
                    163:    if (-e "RS_pause") {unlink("RS_pause"); exit}
                    164:    if (-e "RS_stop")  {unlink("RS_stop"); last}
                    165:    print "$sch $id\n" ;#unless (++$sch % 1);
                    166:    searchmark($id);
                    167:    if ($forbidden{$id}) {next};
                    168:    foreach $fieldnumber (0..$#ss) #перебираем поля
                    169:    {
                    170:       $text=$ss[$fieldnumber];
                    171:       next unless $text;
                    172:       $text=~tr/ёЁ/еЕ/;
                    173:       $text=~s/(${RLrl})p(${RLrl})/$1p$2/gom;
                    174:       $text=~s/p(${RLrl})/р$1/gom;
                    175:       $text=~s/(${RLrl})p/$1р/gom;
                    176:       $text=~s/\s+/ /gmo;
                    177:       @list= $text=~m/(?:(?:${RLrl})+)|(?:[A-Za-z0-9]+)/gom;
                    178: 
                    179: foreach $wordnumber(0..$#list)
                    180:       {
                    181:            $word=uc $list[$wordnumber];
                    182:            next if length $word>$maxwsize;
1.3     ! roma7     183:            next if $stopslovo{$word};
1.1       roma7     184:            if (my $n=$nf{$word}||$newnf{$word}) 
                    185:            {
                    186:                 @n= split ' ',$n;
                    187:                 $nfkvo{$_}++ foreach @n;
                    188:                 $neww2k{$_}.=packword($fieldnumber, $id,$wordnumber%256)
                    189:                      foreach (@n);
                    190:            }
                    191:            else {
                    192:              if ($word=~/^${RLrl}+$/o){ # Русское слово
                    193:             # проанализировать по таблице аффиксов, 
                    194:             # проверить наличие начальных форм в 
                    195:             # nf, а если таких нет, то 
                    196:             # и по словарю. 
                    197:               
                    198:                $nf=&checkit(uc $word,\%words);
                    199:                if (!$nf) {
                    200:                            $nf=(uc $word)."/!";
                    201:                            print UNKNOWN "$nf\n" if $unknown;
                    202:                          }
                    203: 
                    204:               }  else {# нерусское слово
                    205:                          $nf=(uc $word)."/!";
                    206:                          print UNKNOWN "$nf\n" if $unknown;
                    207:                       }
                    208: 
                    209:                foreach $n (split ' ', $nf)
                    210:                {
                    211:                    ($f,$flag)=split '/', $n;
                    212:                    if ($nfnumber=$nfnumber{$f})
                    213:                    {
                    214:                        $newnf{$word}.=" $nfnumber";
                    215:                        $nfkvo{$nfnumber}++;
                    216:                        $a=\$neww2k{$nfnumber};
                    217:                        $$a.=packword($fieldnumber, $id,$wordnumber);
                    218:                        if (length $$a>100) {flushw2k($nfnumber)}
                    219:                    }
                    220:                    else 
                    221:                    {
                    222:                       $nfnumber=addnf(0, $f, $flag,1);
                    223:                       $newnf{uc $word}.=" $nfnumber";
                    224:                       $neww2k{$nfnumber}.=packword($fieldnumber, $id,$wordnumber);
                    225:                    }
                    226:                }
                    227:            }
                    228: 
                    229:       }
                    230:    }
                    231: 
                    232: }
                    233: 
                    234: 
                    235: print "Filling word2question...\n";
                    236: 
                    237: foreach (keys %neww2k)
                    238: { 
                    239:    updateword2question($_,$neww2k{$_});
                    240:    delete $neww2k{$_};
                    241: }
                    242: 
                    243: %neww2k=();
                    244: 
                    245: print "Filling nf...\n";
                    246: $sch=0;
                    247: 
                    248: incnf($_,$nfkvo{$_})  foreach (keys %nfkvo);
                    249: 
                    250: %nfkvo=();
                    251: 
                    252: print "Filling nests...\n";
                    253: $sch=0;
                    254: 
                    255: 
                    256: foreach $w (keys %newnf)
                    257: {
                    258:   print "$sch\n" unless (++$sch % 1000);
                    259:   @nf=split ' ',$newnf{$w};
                    260:   addnest($w,$_) foreach @nf;
                    261: }
                    262: print "$sch nests added\n";
                    263: 
                    264: print TIME "$commonI: \t$sch ";
                    265: print TIME "\t".(time-$initime)."\n";
                    266: %newnf=();
                    267: 
                    268: }
                    269: 
                    270: &untieall;
                    271: 
                    272: unlink "words.tmp";
                    273: unlink "newnf.tmp";
                    274: unlink "neww2k.tmp";
                    275: unlink "nfnumber.tmp";
                    276: unlink "nf.tmp";
                    277: 
                    278: sub flushw2k
                    279: {
                    280:    my ($n)=@_;
                    281:    updateword2question($n,$neww2k{$n});
                    282:    delete $neww2k{$_};
                    283: }
                    284: 
                    285: sub untieall
                    286: {
                    287:   untie %nf;
                    288:   untie %nfnumber;
                    289:   untie %newnf;
                    290:   untie %neww2k;
                    291:   untie %words;
                    292:   
                    293: }
                    294: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>