TL;DR: вот почти накарябал прямо в посте простую утилитку сначала на перле, а потом, если не лень будет, и накарябую на с++, но сдается мне, что она уже есть и как-то называется (прошлый раз тут на лор-е мне даже код запостили, делающий примерно то же, что gnu xargs)
_______________________________________________________
предположим, что есть несколько worker-ов, которые складывают описание достигнутых ими результаты в несколько текстовых файлов — чтобы было предметнее, предположим, что воркеры тянут странички из интернета, а в текстовые файлы последовательно кладут url-ки которые им удалось вытянуть, и которые не удалось вытянуть
утилитка должна читать STDIN и печатать в STDOUT те строки из STDIN, которые не встречаются в текстовых файлах (т.к. эти строки, являющиеся url-ками, уже успешно вытянуты из интернета); таким образов в STDOUT не будут попадать url-ки, которые из интернета уже не надо вытягивать
идея «вместо этого воркеры должны просто проверять наличие файла со страницей из инета» не подходит (долго объяснять почему; между воркерами могут быть гонки на предмет создания файла — но это не основная причина)
так как файлы, заданные в командной строке, растут (но не модифицируются — только append), то утилитка должна периодически дочитывать их, начиная с позиции, в которой она была прошлый раз
можно, но не обязательно, дочитывать эти файлы после каждой строки из STDIN а можно скажем каждую секунду — небольшое дублирование работы воркеров не страшно (а как же гонки? ... написать что ли длинное объяснение? ... короче воркеры могут быть разные — скажем одни воркеры резольвят днс, а вторые фетчат страницы, и вот гонки между резольверам и фетчерами не страшны, но гонки *внутри* фетчеров страшны, т.к. потенциально в один файл могут писать 2 фетчера, и сломают его);
так что вопросы:
1. может такое уже есть? как оно называется?
2. по перлу приходит в голову такая идея и возникает вопрос:
#!/usr/bin/perl -W
use strict;
open FA, "<a.txt" or die;
open FB, "<b.txt" or die;
my $a;
my $b;
my %line_is_already_seen = ();
while( defined($a=<FA>) )
{
$line_is_already_seen{$a}=1;
print STDERR "$a is already seen\n";
}
while( defined($b=<FB>) )
{
$line_is_already_seen{$b}=1;
print STDERR "$b is already seen\n";
}
while(<STDIN>)
{
if( defined($a=<FA>) )
{
$line_is_already_seen{$a}=1;
print STDERR "$a is already seen\n";
}
if( defined($b=<FB>) )
{
$line_is_already_seen{$b}=1;
print STDERR "$b is already seen\n";
}
if( exists($line_is_already_seen{$_}) )
{
print STDERR "skipping:$_ because it is already seen\n";
}
else
{
print STDERR "processing:$_\n";
$line_is_already_seen{$_}=1;
print $_;
}
}
close FB;
close FA;
вопрос: файлы FA и FB пишутся блоками (sync после каждой строки *не* производится), и поэтому последняя строка в них может оказаться неполностью записанной; я правильно понимаю, что покуда ньюлайн в FA не будет записан, $a будет undef, и значит этот код правильный? (или надо заморачиваться со сборкой $a из кусочков? вроде же без этого обходимся)
з.ы. полноценная утилитка должна сначала держать хэш в оперативке, затем скидывать хэш на диск допустим в bdb, а затем колбасить фильтр блума
з.ы.ы. в ранней версии поста был другой код, я надеялся, что из него можно было понять мою мысль — но пришлось дописать