Ticket #12296: 0003-Watchlist-Remove-caching-prog-details-info-improve-l.patch

File 0003-Watchlist-Remove-caching-prog-details-info-improve-l.patch, 20.6 KB (added by Roger Siddons <dizygotheca@…>, 11 years ago)
  • mythtv/libs/libmyth/programtypes.h

    From 394874aedb3e329ac4a000ccf14d9e2bf4b67dda Mon Sep 17 00:00:00 2001
    From: Roger Siddons <dizygotheca@ntlworld.com>
    Date: Tue, 7 Oct 2014 15:53:03 +0100
    Subject: [PATCH 3/6] Watchlist: Remove caching, prog details info & improve
     logging
    
    
    diff --git a/mythtv/libs/libmyth/programtypes.h b/mythtv/libs/libmyth/programtypes.h
    index 2ac2cc2..6275196 100644
    a b typedef enum AvailableStatusTypes { 
    252252} AvailableStatusType; // note stored in uint8_t in ProgramInfo
    253253MPUBLIC QString toString(AvailableStatusType);
    254254
    255 enum WatchListStatus {
    256     wlDeleted = -4,
    257     wlEarlier = -3,
    258     wlWatched = -2,
    259     wlExpireOff = -1
    260 };
    261 
    262255typedef enum AutoExpireTypes {
    263256    kDisableAutoExpire = 0,
    264257    kNormalAutoExpire  = 1,
  • mythtv/programs/mythfrontend/playbackbox.cpp

    diff --git a/mythtv/programs/mythfrontend/playbackbox.cpp b/mythtv/programs/mythfrontend/playbackbox.cpp
    index 23c129f..7927133 100644
    a b static int comp_originalAirDate_rev(const ProgramInfo *a, const ProgramInfo *b) 
    9696        return (dt1 > dt2 ? 1 : -1);
    9797}
    9898
    99 static int comp_recpriority2(const ProgramInfo *a, const ProgramInfo *b)
    100 {
    101     if (a->GetRecordingPriority2() == b->GetRecordingPriority2())
    102         return (a->GetRecordingStartTime() <
    103                 b->GetRecordingStartTime() ? 1 : -1);
    104     else
    105         return (a->GetRecordingPriority2() <
    106                 b->GetRecordingPriority2() ? 1 : -1);
    107 }
    108 
    10999static int comp_recordDate(const ProgramInfo *a, const ProgramInfo *b)
    110100{
    111101    if (a->GetScheduledStartTime().date() == b->GetScheduledStartTime().date())
    static bool comp_originalAirDate_rev_less_than( 
    170160    return comp_originalAirDate_rev(a, b) < 0;
    171161}
    172162
    173 static bool comp_recpriority2_less_than(
    174     const ProgramInfo *a, const ProgramInfo *b)
    175 {
    176     return comp_recpriority2(a, b) < 0;
    177 }
    178 
    179163static bool comp_recordDate_less_than(
    180164    const ProgramInfo *a, const ProgramInfo *b)
    181165{
    bool PlaybackBox::UpdateUILists(void) 
    17741758                {
    17751759                    if (m_watchListAutoExpire && !p->IsAutoExpirable())
    17761760                    {
    1777                         p->SetRecordingPriority2(wlExpireOff);
    1778                         LOG(VB_FILE, LOG_INFO, QString("Auto-expire off:  %1")
    1779                                 .arg(p->GetTitle()));
     1761                        LOG(VB_GUI, LOG_DEBUG,
     1762                            QString("Watchlist: Auto-expire off - %1 %2 (%3x%4)")
     1763                            .arg(MythDate::toString(p->GetScheduledStartTime(),
     1764                                                    Qt::ISODate))
     1765                            .arg(p->GetTitle())
     1766                            .arg(p->GetSeason())
     1767                            .arg(p->GetEpisode()));
    17801768                    }
    17811769                    else if (p->IsWatched())
    17821770                    {
    1783                         p->SetRecordingPriority2(wlWatched);
    1784                         LOG(VB_FILE, LOG_INFO,
    1785                             QString("Marked as 'watched':  %1")
    1786                                 .arg(p->GetTitle()));
     1771                        LOG(VB_GUI, LOG_DEBUG,
     1772                            QString("Watchlist: Watched - %1 %2 (%3x%4)")
     1773                            .arg(MythDate::toString(p->GetScheduledStartTime(),
     1774                                                    Qt::ISODate))
     1775                            .arg(p->GetTitle())
     1776                            .arg(p->GetSeason())
     1777                            .arg(p->GetEpisode()));
    17871778                    }
    17881779                    else
    17891780                    {
    bool PlaybackBox::UpdateUILists(void) 
    18251816                                                            Qt::ISODate))
    18261817                                    .arg(cs).arg(ce));
    18271818                            }
    1828                             else
    1829                             {
    1830                                 p->SetRecordingPriority2(wlEarlier);
    1831                                 LOG(VB_FILE, LOG_INFO,
    1832                                     QString("Not the earliest:  %1")
    1833                                     .arg(p->GetTitle()));
    1834                             }
    18351819                        }
    18361820                        else
    18371821                        {
    bool PlaybackBox::UpdateUILists(void) 
    19241908
    19251909    if (!watchEpisode.empty())
    19261910    {
    1927         // populate watchlist
    1928         foreach (ProgramInfo* wp, watchEpisode.values())
    1929             m_progLists[m_watchGroupLabel].push_front(wp);
    1930         m_progLists[m_watchGroupLabel].setAutoDelete(false);
    1931 
    19321911        QDateTime now = MythDate::current();
    19331912        int baseValue = m_watchListMaxAge * 2 / 3;
    19341913
    bool PlaybackBox::UpdateUILists(void) 
    19381917        QMap<int, int> spanHours;
    19391918        QMap<int, int> delHours;
    19401919        QMap<int, int> nextHours;
     1920        typedef unsigned long long score_type; // 64 bit
     1921        QMultiMap<score_type, ProgramInfo*> watchList; // progs keyed by score
    19411922
    19421923        MSqlQuery query(MSqlQuery::InitCon());
    19431924        query.prepare("SELECT recordid, type, maxepisodes, avg_delay, "
    bool PlaybackBox::UpdateUILists(void) 
    19761957            }
    19771958        }
    19781959
    1979         ProgramList::iterator pit = m_progLists[m_watchGroupLabel].begin();
    1980         while (pit != m_progLists[m_watchGroupLabel].end())
     1960        TitleMap::iterator it = watchEpisode.begin();
     1961        while (it != watchEpisode.end())
    19811962        {
    1982             int recid = (*pit)->GetRecordingRuleID();
     1963            uint score = 0;
     1964            ProgramInfo* p = it.value();
     1965            int recid = p->GetRecordingRuleID();
    19831966            int avgd =  avgDelay[recid];
    19841967
    19851968            if (avgd == 0)
    bool PlaybackBox::UpdateUILists(void) 
    19931976            }
    19941977
    19951978            // add point equal to baseValue for each additional episode
    1996             if (!(*pit)->GetRecordingRuleID() || maxEpisodes[recid] > 0)
    1997                 (*pit)->SetRecordingPriority2(0);
    1998             else
     1979            if (recid && maxEpisodes[recid] == 0)
    19991980            {
    2000                 (*pit)->SetRecordingPriority2(
    2001                     (watchlistCount[extract_watchlist_title(**pit)] - 1) *
    2002                     baseValue);
     1981                score += (watchlistCount[extract_watchlist_title(*p)] - 1) *
     1982                        baseValue;
    20031983            }
    20041984
    20051985            // add points every 3hr leading up to the next recording
    20061986            if (nextHours[recid] > 0 && nextHours[recid] < baseValue * 3)
    20071987            {
    2008                 (*pit)->SetRecordingPriority2(
    2009                     (*pit)->GetRecordingPriority2() +
    2010                     (baseValue * 3 - nextHours[recid]) / 3);
     1988                score += (baseValue * 3 - nextHours[recid]) / 3;
    20111989            }
    20121990
    2013             int hrs = (*pit)->GetScheduledEndTime().secsTo(now) / 3600;
     1991            int hrs = p->GetScheduledEndTime().secsTo(now) / 3600;
    20141992            if (hrs < 1)
    20151993                hrs = 1;
    20161994
    20171995            // add points for a new recording that decrease each hour
    20181996            if (hrs < 42)
    20191997            {
    2020                 (*pit)->SetRecordingPriority2(
    2021                     (*pit)->GetRecordingPriority2() + 42 - hrs);
     1998                score += 42 - hrs;
    20221999            }
    20232000
    20242001            // add points for how close the recorded time of day is to 'now'
    2025             (*pit)->SetRecordingPriority2(
    2026                 (*pit)->GetRecordingPriority2() + abs((hrs % 24) - 12) * 2);
     2002            score += abs((hrs % 24) - 12) * 2;
    20272003
    20282004            // Daily
    20292005            if (spanHours[recid] < 50 ||
    bool PlaybackBox::UpdateUILists(void) 
    20312007            {
    20322008                if (delHours[recid] < m_watchListBlackOut * 4)
    20332009                {
    2034                     (*pit)->SetRecordingPriority2(wlDeleted);
    2035                     LOG(VB_FILE, LOG_INFO,
    2036                         QString("Recently deleted daily:  %1")
    2037                             .arg((*pit)->GetTitle()));
    2038                     pit = m_progLists[m_watchGroupLabel].erase(pit);
     2010                    LOG(VB_GUI, LOG_DEBUG,
     2011                        QString("Watchlist: Recently deleted daily:  %1")
     2012                            .arg(p->GetTitle()));
     2013                    it = watchEpisode.erase(it);
    20392014                    continue;
    20402015                }
    20412016                else
    20422017                {
    2043                     LOG(VB_FILE, LOG_INFO, QString("Daily interval:  %1")
    2044                             .arg((*pit)->GetTitle()));
     2018                    LOG(VB_GUI, LOG_DEBUG, QString("Watchlist: Daily interval:  %1")
     2019                            .arg(p->GetTitle()));
    20452020
    20462021                    if (maxEpisodes[recid] > 0)
    20472022                    {
    2048                         (*pit)->SetRecordingPriority2(
    2049                             (*pit)->GetRecordingPriority2() +
    2050                             (baseValue / 2) + (hrs / 24));
     2023                        score += (baseValue / 2) + (hrs / 24);
    20512024                    }
    20522025                    else
    20532026                    {
    2054                         (*pit)->SetRecordingPriority2(
    2055                             (*pit)->GetRecordingPriority2() +
    2056                             (baseValue / 5) + hrs);
     2027                        score += (baseValue / 5) + hrs;
    20572028                    }
    20582029                }
    20592030            }
    bool PlaybackBox::UpdateUILists(void) 
    20642035            {
    20652036                if (delHours[recid] < (m_watchListBlackOut * 24) - 4)
    20662037                {
    2067                     (*pit)->SetRecordingPriority2(wlDeleted);
    2068                     LOG(VB_FILE, LOG_INFO,
    2069                         QString("Recently deleted weekly:  %1")
    2070                             .arg((*pit)->GetTitle()));
    2071                     pit = m_progLists[m_watchGroupLabel].erase(pit);
     2038                    LOG(VB_GUI, LOG_DEBUG,
     2039                        QString("Watchlist: Recently deleted weekly:  %1")
     2040                            .arg(p->GetTitle()));
     2041                    it = watchEpisode.erase(it);
    20722042                    continue;
    20732043                }
    20742044                else
    20752045                {
    2076                     LOG(VB_FILE, LOG_INFO, QString("Weekly interval: %1")
    2077                             .arg((*pit)->GetTitle()));
     2046                    LOG(VB_GUI, LOG_DEBUG, QString("Watchlist: Weekly interval: %1")
     2047                            .arg(p->GetTitle()));
    20782048
    20792049                    if (maxEpisodes[recid] > 0)
    20802050                    {
    2081                         (*pit)->SetRecordingPriority2(
    2082                             (*pit)->GetRecordingPriority2() +
    2083                             (baseValue / 2) + (hrs / 24));
     2051                        score += (baseValue / 2) + (hrs / 24);
    20842052                    }
    20852053                    else
    20862054                    {
    2087                         (*pit)->SetRecordingPriority2(
    2088                             (*pit)->GetRecordingPriority2() +
    2089                             (baseValue / 3) + (baseValue * hrs / 24 / 4));
     2055                        score += (baseValue / 3) + (baseValue * hrs / 24 / 4);
    20902056                    }
    20912057                }
    20922058            }
    bool PlaybackBox::UpdateUILists(void) 
    20952061            {
    20962062                if (delHours[recid] < (m_watchListBlackOut * 48) - 4)
    20972063                {
    2098                     (*pit)->SetRecordingPriority2(wlDeleted);
    2099                     pit = m_progLists[m_watchGroupLabel].erase(pit);
     2064                    it = watchEpisode.erase(it);
    21002065                    continue;
    21012066                }
    21022067                else
    bool PlaybackBox::UpdateUILists(void) 
    21042069                    // add points for a new Single or final episode
    21052070                    if (hrs < 36)
    21062071                    {
    2107                         (*pit)->SetRecordingPriority2(
    2108                             (*pit)->GetRecordingPriority2() +
    2109                             baseValue * (36 - hrs) / 36);
     2072                        score += baseValue * (36 - hrs) / 36;
    21102073                    }
    21112074
    21122075                    if (avgd != 100)
    21132076                    {
    21142077                        if (maxEpisodes[recid] > 0)
    21152078                        {
    2116                             (*pit)->SetRecordingPriority2(
    2117                                 (*pit)->GetRecordingPriority2() +
    2118                                 (baseValue / 2) + (hrs / 24));
     2079                            score += (baseValue / 2) + (hrs / 24);
    21192080                        }
    21202081                        else
    21212082                        {
    2122                             (*pit)->SetRecordingPriority2(
    2123                                 (*pit)->GetRecordingPriority2() +
    2124                                 (baseValue / 3) + (baseValue * hrs / 24 / 4));
     2083                            score += (baseValue / 3) + (baseValue * hrs / 24 / 4);
    21252084                        }
    21262085                    }
    21272086                    else if ((hrs / 24) < m_watchListMaxAge)
    21282087                    {
    2129                         (*pit)->SetRecordingPriority2(
    2130                             (*pit)->GetRecordingPriority2() +
    2131                             hrs / 24);
     2088                        score += hrs / 24;
    21322089                    }
    21332090                    else
    21342091                    {
    2135                         (*pit)->SetRecordingPriority2(
    2136                             (*pit)->GetRecordingPriority2() +
    2137                             m_watchListMaxAge);
     2092                        score += m_watchListMaxAge;
    21382093                    }
    21392094                }
    21402095            }
    bool PlaybackBox::UpdateUILists(void) 
    21452100
    21462101            if (avgd < 100)
    21472102            {
    2148                 (*pit)->SetRecordingPriority2(
    2149                     (*pit)->GetRecordingPriority2() * (200 - delaypct) / 100);
     2103                score = score * (200 - delaypct) / 100;
    21502104            }
    21512105            else if (avgd > 100)
    21522106            {
    2153                 (*pit)->SetRecordingPriority2(
    2154                     (*pit)->GetRecordingPriority2() * 100 / delaypct);
     2107                score = score * 100 / delaypct;
    21552108            }
    21562109
    2157             LOG(VB_FILE, LOG_INFO, QString(" %1  %2  %3")
    2158                     .arg(MythDate::toString((*pit)->GetScheduledStartTime(),
    2159                                             MythDate::kDateShort))
    2160                     .arg((*pit)->GetRecordingPriority2())
    2161                     .arg((*pit)->GetTitle()));
     2110            // use score as primary key in top 32 bits,
     2111            // use age in secs as a secondary key in low 32 bits to ensure equal
     2112            // scores are ordered oldest first. Copes with progs up to 136 yrs old
     2113            score_type longScore = (static_cast<score_type>(score) << 32)
     2114                    | p->GetScheduledStartTime().secsTo(now);
     2115
     2116            watchList.insert(longScore, p);
    21622117
    2163             ++pit;
     2118            ++it;
     2119
     2120            LOG(VB_GUI, LOG_DEBUG, QString("Watchlist:%1 %2 %3 %4")
     2121                .arg(score, 5)
     2122                .arg(longScore, 14)
     2123                .arg(p->GetTitle())
     2124                .arg(MythDate::toString(p->GetScheduledStartTime(),
     2125                                        MythDate::kDateShort)));
    21642126        }
    2165         std::stable_sort(m_progLists[m_watchGroupLabel].begin(),
    2166                          m_progLists[m_watchGroupLabel].end(),
    2167                          comp_recpriority2_less_than);
     2127
     2128        // populate watchlist group;
     2129        // duplicate keys will appear in reverse alphabetic order
     2130        foreach (ProgramInfo* wp, watchList)
     2131            m_progLists[m_watchGroupLabel].push_front(wp);
     2132
     2133        m_progLists[m_watchGroupLabel].setAutoDelete(false);
    21682134    }
    21692135
    21702136    m_titleList = QStringList("");
  • mythtv/programs/mythfrontend/progdetails.cpp

    diff --git a/mythtv/programs/mythfrontend/progdetails.cpp b/mythtv/programs/mythfrontend/progdetails.cpp
    index 60fff6e..e66a3d4 100644
    a b void ProgDetails::loadPage(void) 
    589589    QString lastRecorded;
    590590    QString nextRecording;
    591591    QString averageTimeShift;
    592     QString watchListScore;
    593     QString watchListStatus;
    594592    QString searchPhrase;
    595593
    596594    if (m_progInfo.GetRecordingRuleID())
    void ProgDetails::loadPage(void) 
    619617                averageTimeShift = tr("%n hour(s)", "",
    620618                                                query.value(2).toInt());
    621619        }
    622         if (recorded)
    623         {
    624             if (m_progInfo.GetRecordingPriority2() > 0)
    625                 watchListScore =
    626                     QString::number(m_progInfo.GetRecordingPriority2());
    627 
    628             if (m_progInfo.GetRecordingPriority2() < 0)
    629             {
    630                 switch (m_progInfo.GetRecordingPriority2())
    631                 {
    632                     case wlExpireOff:
    633                         watchListStatus = tr("Auto-expire off");
    634                         break;
    635                     case wlWatched:
    636                         watchListStatus = tr("Marked as 'watched'");
    637                         break;
    638                     case wlEarlier:
    639                         watchListStatus = tr("Not the earliest episode");
    640                         break;
    641                     case wlDeleted:
    642                         watchListStatus = tr("Recently deleted episode");
    643                         break;
    644                 }
    645             }
    646         }
    647620        if (record->m_searchType != kManualSearch &&
    648621            record->m_description != m_progInfo.GetDescription())
    649622        {
    void ProgDetails::loadPage(void) 
    655628    addItem("LAST_RECORDED", tr("Last Recorded"), lastRecorded);
    656629    addItem("NEXT_RECORDING", tr("Next Recording"), nextRecording);
    657630    addItem("AVERAGE_TIME_SHIFT", tr("Average Time Shift"), averageTimeShift);
    658     addItem("WATCH_LIST_SCORE", tr("Watch List Score"), watchListScore);
    659     addItem("WATCH_LIST_STATUS", tr("Watch List Status"), watchListStatus);
     631    addItem("WATCH_LIST_SCORE", "","");
     632    addItem("WATCH_LIST_STATUS", "","");
    660633    addItem("SEARCH_PHRASE", tr("Search Phrase"), searchPhrase);
    661634
    662635    s.clear();
  • mythtv/themes/MythCenter-wide/htmls/progdetails_page2.html

    diff --git a/mythtv/themes/MythCenter-wide/htmls/progdetails_page2.html b/mythtv/themes/MythCenter-wide/htmls/progdetails_page2.html
    index e35b5fc..98567da 100644
    a b  
    3232    <h1>%LAST_RECORDED_LABEL%</h1> <p>%LAST_RECORDED%</p>
    3333    <h1>%NEXT_RECORDING_LABEL%</h1> <p>%NEXT_RECORDING%</p>
    3434    <h1>%AVERAGE_TIME_SHIFT_LABEL%</h1> <p>%AVERAGE_TIME_SHIFT%</p>
    35     <h1>%WATCH_LIST_SCORE_LABEL%</h1> <p>%WATCH_LIST_SCORE%</p>
    36     <h1>%WATCH_LIST_STATUS_LABEL%</h1> <p>%WATCH_LIST_STATUS%</p>
    3735    <h1>%SEARCH_PHRASE_LABEL%</h1> <p>%SEARCH_PHRASE%</p>
    3836    <h1>%FINDID_LABEL%</h1> <p>%FINDID%</p>
    3937    <h1>%RECORDING_HOST_LABEL%</h1> <p>%RECORDING_HOST%</p>
  • mythtv/themes/MythCenter/htmls/progdetails_page2.html

    diff --git a/mythtv/themes/MythCenter/htmls/progdetails_page2.html b/mythtv/themes/MythCenter/htmls/progdetails_page2.html
    index 2fa3ea3..af6199d 100644
    a b  
    3434    <h1>%LAST_RECORDED_LABEL%</h1> <p>%LAST_RECORDED%</p>
    3535    <h1>%NEXT_RECORDING_LABEL%</h1> <p>%NEXT_RECORDING%</p>
    3636    <h1>%AVERAGE_TIME_SHIFT_LABEL%</h1> <p>%AVERAGE_TIME_SHIFT%</p>
    37     <h1>%WATCH_LIST_SCORE_LABEL%</h1> <p>%WATCH_LIST_SCORE%</p>
    38     <h1>%WATCH_LIST_STATUS_LABEL%</h1> <p>%WATCH_LIST_STATUS%</p>
    3937    <h1>%SEARCH_PHRASE_LABEL%</h1> <p>%SEARCH_PHRASE%</p>
    4038    <h1>%FINDID_LABEL%</h1> <p>%FINDID%</p>
    4139    <h1>%RECORDING_HOST_LABEL%</h1> <p>%RECORDING_HOST%</p>
  • mythtv/themes/Terra/htmls/progdetails_page2.html

    diff --git a/mythtv/themes/Terra/htmls/progdetails_page2.html b/mythtv/themes/Terra/htmls/progdetails_page2.html
    index a1426d6..02963cd 100644
    a b  
    3636    <h1>%LAST_RECORDED_LABEL%</h1> <p>%LAST_RECORDED%</p>
    3737    <h1>%NEXT_RECORDING_LABEL%</h1> <p>%NEXT_RECORDING%</p>
    3838    <h1>%AVERAGE_TIME_SHIFT_LABEL%</h1> <p>%AVERAGE_TIME_SHIFT%</p>
    39     <h1>%WATCH_LIST_SCORE_LABEL%</h1> <p>%WATCH_LIST_SCORE%</p>
    40     <h1>%WATCH_LIST_STATUS_LABEL%</h1> <p>%WATCH_LIST_STATUS%</p>
    4139    <h1>%SEARCH_PHRASE_LABEL%</h1> <p>%SEARCH_PHRASE%</p>
    4240    <h1>%FINDID_LABEL%</h1> <p>%FINDID%</p>
    4341    <h1>%RECORDING_HOST_LABEL%</h1> <p>%RECORDING_HOST%</p>
  • mythtv/themes/default/htmls/progdetails_page2.html

    diff --git a/mythtv/themes/default/htmls/progdetails_page2.html b/mythtv/themes/default/htmls/progdetails_page2.html
    index 40fb94b..4a17980 100644
    a b  
    3333    <h1>%LAST_RECORDED_LABEL%</h1> <p>%LAST_RECORDED%</p>
    3434    <h1>%NEXT_RECORDING_LABEL%</h1> <p>%NEXT_RECORDING%</p>
    3535    <h1>%AVERAGE_TIME_SHIFT_LABEL%</h1> <p>%AVERAGE_TIME_SHIFT%</p>
    36     <h1>%WATCH_LIST_SCORE_LABEL%</h1> <p>%WATCH_LIST_SCORE%</p>
    37     <h1>%WATCH_LIST_STATUS_LABEL%</h1> <p>%WATCH_LIST_STATUS%</p>
    3836    <h1>%SEARCH_PHRASE_LABEL%</h1> <p>%SEARCH_PHRASE%</p>
    3937    <h1>%FINDID_LABEL%</h1> <p>%FINDID%</p>
    4038    <h1>%RECORDING_HOST_LABEL%</h1> <p>%RECORDING_HOST%</p>