Changeset 96

Show
Ignore:
Timestamp:
10/18/06 18:32:22 (7 years ago)
Author:
max
Message:

More intelli-random grabber ordering: keeps track of what C1 grabbers have cached and favors that

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • shepherd

    r94 r96  
    4343use DateTime::Format::Strptime; 
    4444use POSIX qw(strftime); 
     45use Date::Manip; 
    4546use Time::HiRes qw(gettimeofday tv_interval); 
    4647use Algorithm::Diff; 
     48use List::Compare; 
    4749 
    4850# --------------------------------------------------------------------------- 
     
    116118 
    117119print ucfirst($progname) . " v$version\n\n"; 
    118 #print "Cwd: $CWD.\n"; 
    119120 
    120121# Any options Shepherd doesn't understand, we'll pass to the grabber(s) 
     
    224225    my $found_data_percent = 0; 
    225226 
    226     print "\nGrabber stage:\n"; 
     227    print "\nGrabber stage.\n"; 
    227228 
    228229    my $grabber; 
     
    230231    while ($grabber = choose_grabber()) 
    231232    { 
     233 
     234        my $missing_before; 
     235 
    232236        $used_grabbers++; 
    233237 
     
    247251        # very little cost in grabbing that extra data, and we can use it in the reconciler 
    248252        # to verify that everything looks OK. 
    249         if ($components->{$grabber}->{config}->{category} == 1) 
    250         { 
    251             print "CAT1 grabber: grabbing timeslice.\n"; 
     253        if (query_config($grabber, 'category') == 1) 
     254        { 
     255            print "CAT1 grabber: grabbing timeslice.\n" if ($debug); 
    252256            if ($timeslice->{start} != 1) 
    253257            { 
    254258                $comm .= " " .  
    255                          $components->{$grabber}->{config}->{option_offset} . 
     259                         query_config($grabber, 'option_offset') . 
    256260                         " " . 
    257261                         ($timeslice->{start} - 1); 
     
    261265            if ($timeslice->{start} != 1  
    262266                    and  
    263                 !$components->{$grabber}->{config}->{option_offset_eats_days}) 
     267                !query_config($grabber, 'option_offset_eats_days')) 
    264268            { 
    265269                $n -= $timeslice->{start}; 
    266270            } 
    267271            $comm .= " " . 
    268                      $components->{$grabber}->{config}->{option_days} . 
     272                     query_config($grabber, 'option_days') . 
    269273                     " " .  
    270274                     $n; 
     
    279283            write_file($tmpcf, 'temporary channels', [ $tmpchans ], [ 'channels' ]); 
    280284            $comm .= " --channels_file $tmpcf"; 
     285 
     286            if (query_config($grabber, 'cache')) 
     287            { 
     288                $missing_before = convert_chandays_to_list(detect_missing_data()); 
     289            } 
    281290        } 
    282291        else 
    283292        { 
     293            print "CAT2 grabber: grabbing everything.\n" if ($debug); 
    284294            $comm .= " --days $days" if ($days); 
    285295            $comm .= " --offset $opt->{offset}" if ($opt->{offset}); 
     
    306316 
    307317        last if ($found_data_percent >= $channel_ok_threshold_percent); 
     318 
     319        # Record what we grabbed for cacheable C1 grabbers 
     320        if ($missing_before) 
     321        { 
     322 
     323            my $missing_after = convert_chandays_to_list(detect_missing_data()); 
     324            print "Missing before: " . Dumper($missing_before) . "\nMissing after:" . Dumper($missing_after); 
     325            my $list = List::Compare->new($missing_before, $missing_after); 
     326            my @grabbed = $list->get_symmetric_difference(); 
     327            print "Difference: " . Dumper(\@grabbed); 
     328            record_cached($grabber, @grabbed); 
     329            write_config_file(); 
     330        } 
    308331    } 
    309332 
     
    337360            { 
    338361                $gscore->{$_} = 0; 
    339 # Cache stuff: not enabled yet 
    340 #               if ($components->{$_}->{config}->{category} == 1 
    341 #                       and 
    342 #                   $components->{$_}->{config}->{cache}) 
    343 #               { 
    344 #                   $gscore->{$_ . ' [cache]'} = 0; 
    345 #               } 
     362                if (query_config($_, 'category') == 1 
     363                        and 
     364                    query_config($_, 'cache')) 
     365                { 
     366                    $gscore->{$_ . ' [cache]'} = 0; 
     367                } 
    346368            } 
    347369        } 
     
    380402            else 
    381403            { 
    382                 if ($components->{$grabber}->{config}->{category} == 2) 
     404                if (query_config($grabber, 'category') == 2) 
    383405                { 
    384406                    # We might want to run C1 grabbers multiple times 
     
    417439    my $missing_slice = create_missing_slice(); 
    418440 
     441    my $bestdq = 0; 
     442 
    419443    # So! Compare C2 grabbers against the raw missing file, because we'll get 
    420444    # everything. But compare C1 grabbers against the timeslice, because we'll 
     
    426450         
    427451        $hits = 0; 
    428  
    429         if ($grabber =~ /(.*) \[cache\]$/) 
    430         { 
    431             $hits = find_cache_hits($1, $missing); 
    432             $cat = 2; 
    433             $dq = $components->{$1}->{config}->{quality}; 
     452        $cat = query_config($grabber, 'category'); 
     453        $dq = query_config($grabber, 'quality'); 
     454 
     455        if ($grabber =~ /\[cache\]/) 
     456        { 
     457            $hits = find_cache_hits($grabber, $missing); 
    434458        } 
    435459        else 
    436460        { 
    437             my $key = $missing; 
    438             if ($components->{$grabber}->{config}->{category} == 1) 
     461            my $key; 
     462            if ($cat == 1) 
    439463            { 
    440464                $key = $missing_slice; 
     465                print "Grabber $grabber is Category 1: comparing capability to best timeslice.\n" if ($debug); 
     466            } 
     467            else 
     468            { 
     469                $key = $missing; 
     470                print "Grabber $grabber is Category 2: comparing capability to all wanted channels and days.\n" if ($debug); 
    441471            } 
    442472            foreach my $day (sort keys %$key) 
     
    444474                my $val = supports_day($grabber, $day); 
    445475                next unless ($val); 
    446                 print "Day $day:"; 
     476                print "Day $day:" if ($debug); 
    447477                foreach my $ch (@{$key->{$day}}) 
    448478                { 
     
    455485                print "\n"; 
    456486                $hits = 1 if ($hits > 0 and $hits < 1); 
    457  
    458                 $cat = $components->{$grabber}->{config}->{category}; 
    459                 unless ($cat) 
    460                 { 
    461                     print "WARNING: Grabber $grabber has no category support ". 
    462                     "in config.\n"; 
    463                     $cat = 1; 
    464                 } 
    465  
    466                 $dq = $components->{$grabber}->{config}->{quality}; 
    467                 unless ($dq) 
    468                 { 
    469                     print "WARNING: Grabber $grabber has no quality support ". 
    470                     "in config.\n"; 
    471                     $dq = 1; 
    472                 } 
    473             } 
    474         } 
     487            } 
     488        } 
     489 
    475490        $mult = 1; 
    476         $mult++ if ($cat == 2); 
     491        $mult += 2 if ($cat == 2); 
    477492        $mult *= 2 ** ($dq-1); 
     493        $score = int($hits * $mult); 
    478494 
    479495        $score = int($hits * $mult); 
     
    481497        $gscore->{$grabber} = $score; 
    482498        $total += $score; 
    483     } 
     499 
     500        # Keep track of the best quality of valid grabbers 
     501        if ($score and $dq > $bestdq) 
     502        { 
     503            $bestdq = $dq; 
     504        } 
     505    } 
     506 
     507    # Eliminate grabbers of data quality 1 if there are any quality 2s 
     508    # or 3s present. 
     509    foreach (keys %$gscore) 
     510    { 
     511        if ($gscore->{$_} 
     512                and 
     513            query_config($_, 'quality') == 1 
     514                and 
     515            $bestdq > 1) 
     516        { 
     517            $total -= $gscore->{$_}; 
     518            $gscore->{$_} = 0; 
     519            print "Zeroing grabber $_ due to low data quality.\n" if ($debug); 
     520        } 
     521    } 
     522 
    484523    return $total; 
    485524} 
     
    489528    my ($grabber, $ch) = @_; 
    490529 
    491     my $channels_supported = $components->{$grabber}->{config}->{channels}; 
     530    my $channels_supported = query_config($grabber, 'channels'); 
    492531    unless (defined $channels_supported) 
    493532    { 
     
    508547    my ($grabber, $day) = @_; 
    509548 
    510     return 0 unless ($day <= $components->{$grabber}->{config}->{max_days}); 
    511     return 0.5 if ($day > $components->{$grabber}->{config}->{max_reliable_days}); 
     549    return 0 unless ($day <= query_config($grabber, 'max_days')); 
     550    return 0.5 if ($day > query_config($grabber, 'max_reliable_days')); 
    512551    return 1; 
    513552} 
     
    517556    my ($grabber, $missing) = @_; 
    518557 
    519     return 5; 
     558    if ($grabber =~ /(.*) \[cache\]/) 
     559    { 
     560        $grabber = $1; 
     561    } 
     562 
     563    return 0 unless ($components->{$grabber}->{cached}); 
     564 
     565    my $hits = 0; 
     566 
     567    foreach my $day (keys %$missing) 
     568    { 
     569        my $date = substr(DateCalc("today", "+ " . ($day - 1) . " days"), 0, 8); 
     570        foreach my $ch (@{$missing->{$day}}) 
     571        { 
     572            $hits++ if (grep(/^$date:$ch$/, @{$components->{$grabber}->{cached}})); 
     573        } 
     574    } 
     575    return $hits; 
    520576} 
    521577 
     
    525581# made more fine-grained if we think grabbers will support that. 
    526582# 
     583# TODO: Currently buggy in that it thinks we need 24 hours worth of 
     584# data for day 1 when we don't. 
     585# 
    527586sub detect_missing_data 
    528587{ 
     
    531590    my $timeslots_per_day = (24 * 60 * 60) / $timeslot_size; 
    532591 
     592    # print "Channel data:\n" . Dumper($channel_data); 
    533593    foreach my $ch (keys %$channels) 
    534594    { 
     
    615675    return $ret; 
    616676} 
     677 
     678sub record_cached 
     679{ 
     680    my ($grabber, @grabbed) = shift; 
     681 
     682    print "Recording cache for grabber $grabber.\n" if ($debug); 
     683 
     684    my $gcache = $components->{$grabber}->{cached}; 
     685    $gcache = [ ] unless ($gcache); 
     686    my @newcache; 
     687    my $today = strftime("%Y%m%d", localtime); 
     688 
     689    # remove old chandays 
     690    foreach my $chanday (@$gcache) 
     691    { 
     692        $chanday =~ /(\d+):(.*)/; 
     693        if ($1 >= $today) 
     694        { 
     695            push (@newcache, $chanday); 
     696        } 
     697    } 
     698 
     699    # record new chandays 
     700    foreach (@grabbed) 
     701    { 
     702        push (@newcache, $_) unless (grep(/^$_$/, @newcache)); 
     703    } 
     704    $components->{$grabber}->{cached} = [ @newcache ]; 
     705} 
     706 
     707# Takes a 'missing' hash and returns it as a list like this: 
     708# ( "20061018:ABC", "20061018:Seven", ... ) 
     709sub convert_chandays_to_list 
     710{ 
     711    my $h = shift; 
     712 
     713    my @ret; 
     714    foreach my $day (keys %$h) 
     715    { 
     716        my $date = substr(DateCalc("today", "+ " . ($day - 1) . " days"), 0, 8); 
     717        foreach my $ch (@{$h->{$day}}) 
     718        { 
     719            push (@ret, "$date:$ch"); 
     720        } 
     721    } 
     722    @ret = sort @ret; 
     723    return \@ret; 
     724} 
     725 
    617726 
    618727# interpret xmltv data from this grabber/postprocessor 
     
    13201429    } 
    13211430    return @ret; 
     1431} 
     1432 
     1433sub query_config 
     1434{ 
     1435    my ($grabber, $key) = @_; 
     1436 
     1437    if ($grabber =~ /(.*) \[cache\]/) 
     1438    { 
     1439        $grabber = $1; 
     1440    } 
     1441    return undef unless ($components->{$grabber}); 
     1442    return $components->{$grabber}->{config}->{$key}; 
    13221443} 
    13231444