Ticket #3326: multi-sched-multimap-v4.patch
File multi-sched-multimap-v4.patch, 28.2 KB (added by , 17 years ago) |
---|
-
programs/mythbackend/scheduler.h
2 2 #define SCHEDULER_H_ 3 3 4 4 // C++ headers 5 #include <map> 5 6 #include <deque> 6 7 #include <vector> 7 8 using namespace std; … … 35 36 typedef RecList::iterator RecIter; 36 37 37 38 typedef vector<int> InputGroupList; 39 typedef QMap<int, RecList> CardListMap; 38 40 41 typedef multimap<uint64_t, ProgramInfo*> ConflictMap; 42 39 43 class Scheduler : public QObject 40 44 { 41 45 public: … … 99 103 void PruneOverlaps(void); 100 104 void BuildListMaps(void); 101 105 void ClearListMaps(void); 106 107 bool IsConflicting(const ProgramInfo *p, const ProgramInfo *q, 108 bool openEnd) const; 109 110 bool IsSameProgram(const ProgramInfo *a, const ProgramInfo *b) const; 111 bool IsSameTimeslot(const ProgramInfo *a, const ProgramInfo *b) const; 112 102 113 bool FindNextConflict(const RecList &cardlist, 103 114 const ProgramInfo *p, RecConstIter &iter, 104 115 bool openEnd = false) const; 105 const ProgramInfo *FindConflict(const QMap<int, RecList> &reclists, 106 const ProgramInfo *p, bool openEnd = false) const; 116 117 ProgramInfo *FindAnyConflict( 118 ConflictMap &map, const ProgramInfo *p, bool openend) const; 119 120 RecList FindAllConflict( 121 ConflictMap &map, const ProgramInfo *p, bool openend) const; 122 107 123 void MarkOtherShowings(ProgramInfo *p); 108 124 void MarkShowingsList(RecList &showinglist, ProgramInfo *p); 109 125 void BackupRecStatus(void); … … 137 153 RecList reclist; 138 154 RecList worklist; 139 155 RecList retrylist; 140 QMap<int, RecList> cardlistmap; 156 ConflictMap conflictmap; 157 QMap<const ProgramInfo*, RecList*> splistmap; 141 158 QMap<int, RecList> recordidlistmap; 142 159 QMap<QString, RecList> titlelistmap; 143 160 QMap<int, InputGroupList> inputgroupmap; … … 170 187 QDateTime livetvTime; 171 188 int livetvpriority; 172 189 QMap<QString, bool> hasLaterList; 190 191 // cache IsSameProgram() 192 typedef pair<const ProgramInfo*,const ProgramInfo*> IsSameKey; 193 typedef QMap<IsSameKey,bool> IsSameCacheType; 194 mutable IsSameCacheType cache_is_same_program; 195 mutable IsSameCacheType cache_is_same_timeslot; 173 196 }; 174 197 175 198 #endif -
programs/mythbackend/scheduler.cpp
302 302 303 303 BuildInputGroupMap(); 304 304 305 VERBOSE(VB_ SCHEDULE, "BuildWorkList...");305 VERBOSE(VB_IMPORTANT, "BuildWorkList..."); 306 306 BuildWorkList(); 307 VERBOSE(VB_ SCHEDULE, "AddNewRecords...");307 VERBOSE(VB_IMPORTANT, "AddNewRecords..."); 308 308 AddNewRecords(); 309 VERBOSE(VB_ SCHEDULE, "AddNotListed...");309 VERBOSE(VB_IMPORTANT, "AddNotListed..."); 310 310 AddNotListed(); 311 311 312 VERBOSE(VB_ SCHEDULE, "Sort by time...");312 VERBOSE(VB_IMPORTANT, "Sort by time..."); 313 313 SORT_RECLIST(worklist, comp_overlap); 314 VERBOSE(VB_ SCHEDULE, "PruneOverlaps...");314 VERBOSE(VB_IMPORTANT, "PruneOverlaps..."); 315 315 PruneOverlaps(); 316 316 317 VERBOSE(VB_ SCHEDULE, "Sort by priority...");317 VERBOSE(VB_IMPORTANT, "Sort by priority..."); 318 318 SORT_RECLIST(worklist, comp_priority); 319 VERBOSE(VB_ SCHEDULE, "BuildListMaps...");319 VERBOSE(VB_IMPORTANT, "BuildListMaps..."); 320 320 BuildListMaps(); 321 VERBOSE(VB_ SCHEDULE, "SchedNewRecords...");321 VERBOSE(VB_IMPORTANT, "SchedNewRecords..."); 322 322 SchedNewRecords(); 323 VERBOSE(VB_ SCHEDULE, "SchedPreserveLiveTV...");323 VERBOSE(VB_IMPORTANT, "SchedPreserveLiveTV..."); 324 324 SchedPreserveLiveTV(); 325 VERBOSE(VB_ SCHEDULE, "ClearListMaps...");325 VERBOSE(VB_IMPORTANT, "ClearListMaps..."); 326 326 ClearListMaps(); 327 327 328 VERBOSE(VB_ SCHEDULE, "Sort by time...");328 VERBOSE(VB_IMPORTANT, "Sort by time..."); 329 329 SORT_RECLIST(worklist, comp_redundant); 330 VERBOSE(VB_ SCHEDULE, "PruneRedundants...");330 VERBOSE(VB_IMPORTANT, "PruneRedundants..."); 331 331 PruneRedundants(); 332 332 333 VERBOSE(VB_ SCHEDULE, "Sort by time...");333 VERBOSE(VB_IMPORTANT, "Sort by time..."); 334 334 SORT_RECLIST(worklist, comp_recstart); 335 VERBOSE(VB_ SCHEDULE, "ClearWorkList...");335 VERBOSE(VB_IMPORTANT, "ClearWorkList..."); 336 336 bool res = ClearWorkList(); 337 337 338 338 return res; … … 750 750 erase_nulls(worklist); 751 751 } 752 752 753 const static bool is_conflict_dbg = false; 754 static vector<uint> stats_i; 755 static vector<uint> stats_j; 756 static vector<uint> stats_k; 757 static vector<uint> stats_found; 758 static vector<uint> stats_all_i; 759 static vector<uint> stats_all_j; 760 static vector<uint> stats_all_k; 761 static vector<uint> stats_all_found; 762 763 static uint insert(ConflictMap &cmap, const InputGroupList &input_groups, ProgramInfo *p) 764 { 765 uint insert_cnt = 0; 766 uint64_t btimeX = min(p->recstartts.toTime_t(), 767 p->startts.toTime_t()); 768 uint64_t etimeX = max(p->recendts.toTime_t(), 769 p->endts.toTime_t()); 770 771 InputGroupList::const_iterator it = input_groups.begin(); 772 for (; it != input_groups.end(); ++it) 773 { 774 uint64_t btime = (((uint64_t)(*it)) << 32) + btimeX; 775 uint64_t etime = (((uint64_t)(*it)) << 32) + etimeX; 776 for (; btime < etime; btime += 2000) 777 { 778 cmap.insert(pair<uint64_t, ProgramInfo*>(btime, p)); 779 insert_cnt++; 780 } 781 cmap.insert(pair<uint64_t, ProgramInfo*>(etime, p)); 782 insert_cnt++; 783 } 784 785 return insert_cnt; 786 } 787 753 788 void Scheduler::BuildListMaps(void) 754 789 { 790 uint tcnt = 0, ccnt = 0; 791 VERBOSE(VB_IMPORTANT, "BuildListMaps -- begin"); 792 755 793 RecIter i = worklist.begin(); 756 794 for ( ; i != worklist.end(); i++) 757 795 { … … 760 798 p->recstatus == rsWillRecord || 761 799 p->recstatus == rsUnknown) 762 800 { 763 cardlistmap[p->cardid].push_back(p); 801 ++tcnt; 802 ccnt += insert(conflictmap, inputgroupmap[p->inputid], p); 764 803 titlelistmap[p->title].push_back(p); 765 804 recordidlistmap[p->recordid].push_back(p); 766 805 } 767 806 } 807 808 VERBOSE(VB_IMPORTANT, "BuildListMaps title cnt: " 809 <<tcnt<<" conflict cnt: "<<ccnt); 810 811 gContext->ClearSettingsCache(); 812 uint max_sz = gContext->GetNumSetting("BuildListMapsTemp", 100); 813 uint64_t mht = 0, mhc = 0; 814 815 QMap<QString, RecList>::const_iterator it = titlelistmap.begin(); 816 for (; it != titlelistmap.end(); ++it) 817 { 818 uint sz = (*it).size(); 819 820 if (sz < max_sz) 821 continue; 822 823 VERBOSE(VB_IMPORTANT, QString("sz %1 title: '%2'") 824 .arg(sz,4).arg(it.key())); 825 826 uint64_t startt, endt; rdtsc(startt); 827 for (uint i = 0; i < sz; i++) 828 splistmap[(*it)[i]] = NULL; 829 830 for (uint i = 0; i < sz; i++) 831 { 832 const ProgramInfo *p = (*it)[i]; 833 for (uint j = i+1; j < sz; j++) 834 { 835 const ProgramInfo *q = (*it)[j]; 836 if (!p->IsSameTimeslot(*q) || !IsSameProgram(p,q)) 837 continue; 838 839 // place q in p's set 840 if (!splistmap[p]) 841 { 842 splistmap[p] = new RecList; 843 splistmap[p]->push_back((*it)[i]); 844 } 845 846 splistmap[q] = splistmap[p]; 847 splistmap[q]->push_back((*it)[j]); 848 849 break; 850 } 851 } 852 rdtsc(endt); mht += (endt - startt); mhc++; 853 } 854 cout<<QString("Build splistmap: %1 %2").arg(mhc,4).arg(mht,12)<<endl; 855 856 VERBOSE(VB_IMPORTANT, "BuildListMaps -- end"); 857 858 stats_i.clear(); 859 stats_j.clear(); 860 stats_k.clear(); 861 stats_found.clear(); 862 stats_all_i.clear(); 863 stats_all_j.clear(); 864 stats_all_k.clear(); 865 stats_all_found.clear(); 768 866 } 769 867 770 868 void Scheduler::ClearListMaps(void) 771 869 { 772 c ardlistmap.clear();870 conflictmap.clear(); 773 871 titlelistmap.clear(); 774 872 recordidlistmap.clear(); 873 cache_is_same_program.clear(); 874 cache_is_same_timeslot.clear(); 875 // TODO clear out splistmap RecList's 876 splistmap.clear(); 775 877 } 776 878 777 bool Scheduler::FindNextConflict( 778 const RecList &cardlist, 779 const ProgramInfo *p, 780 RecConstIter &j, 781 bool openEnd) const 879 bool Scheduler::IsConflicting( 880 const ProgramInfo *p, const ProgramInfo *q, bool openEnd) const 782 881 { 783 bool is_conflict_dbg = false; 882 //cerr<<":"; 883 if (!Recording(q)) 884 return false; 784 885 785 for ( ; j != cardlist.end(); j++) 786 { 787 const ProgramInfo *q = *j; 886 if (p == q) 887 return false; 788 888 789 if (p == q)790 continue;889 if (is_conflict_dbg) 890 cout << QString("\n comparing with '%1' ").arg(q->title); 791 891 792 if (!Recording(q))793 continue;794 892 if (p->cardid != 0 && (p->cardid != q->cardid) && 893 !GetSharedInputGroup(p->inputid, q->inputid)) 894 { 795 895 if (is_conflict_dbg) 796 cout << QString("\n comparing with '%1' ").arg(q->title); 896 cout << " cardid== "; 897 return false; 898 } 797 899 798 if (p->cardid != 0 && (p->cardid != q->cardid) && 799 !GetSharedInputGroup(p->inputid, q->inputid)) 900 if (openEnd && p->chanid != q->chanid) 901 { 902 if (p->recendts < q->recstartts || p->recstartts > q->recendts) 800 903 { 801 904 if (is_conflict_dbg) 802 cout << " cardid==";803 continue;905 cout << " no-overlap "; 906 return false; 804 907 } 805 806 if (openEnd && p->chanid != q->chanid) 908 } 909 else 910 { 911 if (p->recendts <= q->recstartts || p->recstartts >= q->recendts) 807 912 { 808 if (p->recendts < q->recstartts || p->recstartts > q->recendts) 809 { 810 if (is_conflict_dbg) 811 cout << " no-overlap "; 812 continue; 813 } 913 if (is_conflict_dbg) 914 cout << " no-overlap "; 915 return false; 814 916 } 815 else 816 { 817 if (p->recendts <= q->recstartts || p->recstartts >= q->recendts) 818 { 819 if (is_conflict_dbg) 820 cout << " no-overlap "; 821 continue; 822 } 823 } 917 } 824 918 825 if (is_conflict_dbg) 826 cout << "\n" << 827 QString(" cardid's: %1, %2 ").arg(p->cardid).arg(q->cardid) + 828 QString("Shared input group: %1 ") 829 .arg(GetSharedInputGroup(p->inputid, q->inputid)) + 830 QString("mplexid's: %1, %2") 831 .arg(p->GetMplexID()).arg(q->GetMplexID()); 919 if (is_conflict_dbg) 920 { 921 cout << "\n" << 922 QString(" cardid's: %1, %2 ").arg(p->cardid).arg(q->cardid) + 923 QString("Shared input group: %1 ") 924 .arg(GetSharedInputGroup(p->inputid, q->inputid)) + 925 QString("mplexid's: %1, %2") 926 .arg(p->GetMplexID()).arg(q->GetMplexID()); 927 } 832 928 833 834 835 836 837 838 839 continue;840 929 // if two inputs are in the same input group we have a conflict 930 // unless the programs are on the same multiplex. 931 if (p->cardid && (p->cardid != q->cardid) && 932 GetSharedInputGroup(p->inputid, q->inputid) && 933 p->GetMplexID() && (p->GetMplexID() == q->GetMplexID())) 934 { 935 return false; 936 } 841 937 842 843 938 if (is_conflict_dbg) 939 cout << "\n Found conflict" << endl; 844 940 845 return true; 941 return true; 942 } 943 944 bool Scheduler::IsSameProgram( 945 const ProgramInfo *a, const ProgramInfo *b) const 946 { 947 IsSameKey X(a,b); 948 IsSameCacheType::const_iterator it = cache_is_same_program.find(X); 949 if (it != cache_is_same_program.end()) 950 return *it; 951 952 IsSameKey Y(b,a); 953 bool val = a->IsSameProgram(*b); 954 cache_is_same_program[X] = val; 955 cache_is_same_program[Y] = val; 956 return val; 957 } 958 959 bool Scheduler::IsSameTimeslot( 960 const ProgramInfo *a, const ProgramInfo *b) const 961 { 962 IsSameKey X(a,b); 963 IsSameCacheType::const_iterator it = cache_is_same_timeslot.find(X); 964 if (it != cache_is_same_timeslot.end()) 965 return *it; 966 967 IsSameKey Y(b,a); 968 bool val = a->IsSameTimeslot(*b); 969 cache_is_same_timeslot[X] = val; 970 cache_is_same_timeslot[Y] = val; 971 return val; 972 } 973 974 bool Scheduler::FindNextConflict( 975 const RecList &cardlist, 976 const ProgramInfo *p, 977 RecConstIter &j, 978 bool openEnd) const 979 { 980 cerr<<"FindNextConflict(RecList...)"<<endl; 981 for ( ; j != cardlist.end(); j++) 982 { 983 if (IsConflicting(p, *j, openEnd)) 984 return true; 846 985 } 847 986 848 987 if (is_conflict_dbg) … … 851 990 return false; 852 991 } 853 992 854 const ProgramInfo *Scheduler::FindConflict( 855 const QMap<int, RecList> &reclists, 856 const ProgramInfo *p, 857 bool openend) const 993 ProgramInfo *Scheduler::FindAnyConflict( 994 ConflictMap &cmap, const ProgramInfo *p, bool openend) const 858 995 { 859 bool is_conflict_dbg = false; 996 QMap<ProgramInfo*,ProgramInfo*> dups; 997 uint i = 0, j = 0, k = 0; 998 uint64_t btimeX = p->recstartts.toTime_t() - 2000; 999 uint64_t etimeX = p->recendts.toTime_t() + 1; 860 1000 861 QMap<int, RecList>::const_iterator it = reclists.begin(); 862 for (; it != reclists.end(); ++it) 1001 const InputGroupList &ingrp = inputgroupmap[p->inputid]; 1002 InputGroupList::const_iterator grpit = ingrp.begin(); 1003 const ProgramInfo *last = NULL; 1004 for (; grpit != ingrp.end(); ++grpit) 863 1005 { 864 if (is_conflict_dbg) 1006 uint64_t btime = btimeX | (((uint64_t)*grpit) << 32); 1007 ConflictMap::iterator beg = cmap.lower_bound(btime); 1008 uint64_t etime = etimeX | (((uint64_t)*grpit) << 32); 1009 ConflictMap::iterator end = cmap.upper_bound(etime); 1010 1011 ConflictMap::iterator it = beg; 1012 for (; it != end; ++it) 865 1013 { 866 cout << QString("Checking '%1' for conflicts on cardid %2") 867 .arg(p->title).arg(it.key()); 1014 if ((it->second == last) || dups[it->second]) 1015 { 1016 i++; 1017 continue; 1018 } 1019 last = dups[it->second] = it->second; 1020 j++; 1021 if (IsConflicting(p, it->second, openend)) 1022 { 1023 stats_i.push_back(i); 1024 stats_j.push_back(j); 1025 stats_k.push_back(k); 1026 stats_found.push_back(1); 1027 return it->second; 1028 } 868 1029 } 1030 } 869 1031 870 const RecList &cardlist = *it; 871 RecConstIter k = cardlist.begin(); 872 if (FindNextConflict(cardlist, p, k, openend)) 1032 stats_i.push_back(i); 1033 stats_j.push_back(j); 1034 stats_k.push_back(k); 1035 stats_found.push_back(0); 1036 1037 return NULL; 1038 } 1039 1040 RecList Scheduler::FindAllConflict( 1041 ConflictMap &cmap, const ProgramInfo *p, bool openend) const 1042 { 1043 RecList list; 1044 1045 QMap<ProgramInfo*,ProgramInfo*> dups; 1046 uint i = 0, j = 0, k = 0; 1047 uint64_t btimeX = p->recstartts.toTime_t() - 2000; 1048 uint64_t etimeX = p->recendts.toTime_t() + 1; 1049 1050 const InputGroupList &ingrp = inputgroupmap[p->inputid]; 1051 InputGroupList::const_iterator grpit = ingrp.begin(); 1052 const ProgramInfo *last = NULL; 1053 for (; grpit != ingrp.end(); ++grpit) 1054 { 1055 uint64_t btime = btimeX | (((uint64_t)*grpit) << 32); 1056 ConflictMap::iterator beg = cmap.lower_bound(btime); 1057 uint64_t etime = etimeX | (((uint64_t)*grpit) << 32); 1058 ConflictMap::iterator end = cmap.upper_bound(etime); 1059 1060 ConflictMap::iterator it = beg; 1061 for (; it != end; ++it) 873 1062 { 874 return *k; 1063 if ((it->second == last) || dups[it->second]) 1064 { 1065 i++; 1066 continue; 1067 } 1068 last = dups[it->second] = it->second; 1069 1070 const ProgramInfo *q = last; 1071 if (openend && p->chanid != q->chanid) 1072 { 1073 if (p->recendts < q->recstartts || p->recstartts > q->recendts) 1074 { 1075 k++; 1076 continue; 1077 } 1078 } 1079 else 1080 { 1081 if (p->recendts <= q->recstartts || p->recstartts >= q->recendts) 1082 { 1083 k++; 1084 continue; 1085 } 1086 } 1087 1088 j++; 1089 if (IsConflicting(p, it->second, openend)) 1090 list.push_back(it->second); 875 1091 } 876 1092 } 877 1093 878 return NULL; 1094 stats_all_i.push_back(i); 1095 stats_all_j.push_back(j); 1096 stats_all_k.push_back(k); 1097 stats_all_found.push_back(list.size()); 1098 1099 return list; 879 1100 } 880 1101 881 1102 void Scheduler::MarkOtherShowings(ProgramInfo *p) 882 1103 { 883 RecList *showinglist = &titlelistmap[p->title]; 1104 QMap<const ProgramInfo*, RecList*>::iterator sit = splistmap.find(p); 1105 RecList *showinglist = NULL; 1106 if (sit != splistmap.end()) 1107 showinglist = *sit; 1108 else 1109 showinglist = &titlelistmap[p->title]; 884 1110 885 MarkShowingsList(*showinglist, p); 1111 if (showinglist) 1112 MarkShowingsList(*showinglist, p); 886 1113 887 1114 if (p->rectype == kFindOneRecord || 888 1115 p->rectype == kFindDailyRecord || … … 901 1128 902 1129 void Scheduler::MarkShowingsList(RecList &showinglist, ProgramInfo *p) 903 1130 { 1131 uint me = 0; 1132 uint ign = 0; 1133 uint sametime = 0; 1134 uint later = 0; 1135 uint earlier = 0; 1136 uint other = 0; 1137 904 1138 RecIter i = showinglist.begin(); 905 1139 for ( ; i != showinglist.end(); i++) 906 1140 { 907 1141 ProgramInfo *q = *i; 908 1142 if (q == p) 1143 { 1144 me++; 909 1145 continue; 1146 } 910 1147 if (q->recstatus != rsUnknown && 911 1148 q->recstatus != rsWillRecord && 912 1149 q->recstatus != rsEarlierShowing && 913 1150 q->recstatus != rsLaterShowing) 1151 { 1152 ign++; 914 1153 continue; 1154 } 1155 915 1156 if (q->IsSameTimeslot(*p)) 1157 { 916 1158 q->recstatus = rsLaterShowing; 1159 sametime++; 1160 } 917 1161 else if (q->rectype != kSingleRecord && 918 1162 q->rectype != kOverrideRecord && 919 q->IsSameProgram(*p))1163 IsSameProgram(q,p)) 920 1164 { 921 1165 if (q->recstartts < p->recstartts) 1166 { 1167 later++; 922 1168 q->recstatus = rsLaterShowing; 1169 } 923 1170 else 1171 { 1172 earlier++; 924 1173 q->recstatus = rsEarlierShowing; 1174 } 925 1175 } 1176 else 1177 { 1178 other++; 1179 } 926 1180 } 1181 1182 uint max_sz = gContext->GetNumSetting("BuildListMapsTemp", 100); 1183 if (showinglist.size() >= max_sz) 1184 { 1185 cout<<QString("title: %1").arg(p->title,20) 1186 <<"m:"<<me<<" ign: "<<ign<<" st: "<<sametime<<" sml: "<<later 1187 <<" sme: "<<earlier<<" other: "<<other<<endl; 1188 } 927 1189 } 928 1190 929 1191 void Scheduler::BackupRecStatus(void) … … 953 1215 if (p->recstatus == rsRecording) 954 1216 return false; 955 1217 956 RecList *showinglist = &titlelistmap[p->title]; 1218 QMap<const ProgramInfo*, RecList*>::iterator sit = splistmap.find(p); 1219 RecList *showinglist = NULL; 1220 if (sit != splistmap.end()) 1221 showinglist = *sit; 1222 else 1223 showinglist = &titlelistmap[p->title]; 957 1224 1225 if (!showinglist) 1226 return false; 1227 958 1228 if (p->rectype == kFindOneRecord || 959 1229 p->rectype == kFindDailyRecord || 960 1230 p->rectype == kFindWeeklyRecord) … … 980 1250 continue; 981 1251 if (!p->IsSameTimeslot(*q)) 982 1252 { 983 if (! p->IsSameProgram(*q))1253 if (!IsSameProgram(p,q)) 984 1254 continue; 985 1255 if ((p->rectype == kSingleRecord || 986 1256 p->rectype == kOverrideRecord)) … … 1032 1302 } 1033 1303 } 1034 1304 1035 const ProgramInfo *conflict = FindConflict(cardlistmap, q);1305 ProgramInfo *conflict = FindAnyConflict(conflictmap, q, false); 1036 1306 if (conflict) 1037 1307 { 1038 1308 PrintRec(conflict, " !"); … … 1067 1337 return false; 1068 1338 } 1069 1339 1340 static QMap<QString,uint> othershow; 1341 1070 1342 void Scheduler::SchedNewRecords(void) 1071 1343 { 1072 1344 VERBOSE(VB_SCHEDULE, "Scheduling:"); 1345 uint64_t mot = 0, moc = 0; 1346 uint64_t fat = 0, fac = 0; 1347 uint64_t mot2 = 0, moc2 = 0; 1348 uint64_t mot3 = 0, moc3 = 0; 1349 uint64_t mht = 0, mhc = 0; 1073 1350 1074 1351 bool openEnd = (bool)gContext->GetNumSetting("SchedOpenEnd", 0); 1075 1352 1353 uint max_sz = gContext->GetNumSetting("BuildListMapsTemp", 100); 1354 othershow.clear(); 1355 1076 1356 RecIter i = worklist.begin(); 1077 1357 while (i != worklist.end()) 1078 1358 { 1079 1359 ProgramInfo *p = *i; 1080 1360 if (p->recstatus == rsRecording) 1361 { 1362 uint64_t startt, endt; rdtsc(startt); 1081 1363 MarkOtherShowings(p); 1364 rdtsc(endt); mot += (endt - startt); moc++; 1365 } 1082 1366 else if (p->recstatus == rsUnknown) 1083 1367 { 1084 const ProgramInfo *conflict = FindConflict(cardlistmap, p, openEnd); 1368 uint64_t startt, endt; rdtsc(startt); 1369 ProgramInfo *conflict = FindAnyConflict(conflictmap, p, openEnd); 1370 rdtsc(endt); fat += (endt - startt); fac++; 1371 1085 1372 if (!conflict) 1086 1373 { 1087 1374 p->recstatus = rsWillRecord; … … 1101 1388 VERBOSE(VB_GENERAL, msg); 1102 1389 } 1103 1390 1104 MarkOtherShowings(p); 1391 RecList *showinglist = &titlelistmap[p->title]; 1392 if (showinglist->size() >= max_sz) 1393 { 1394 othershow[p->title] = showinglist->size(); 1395 uint64_t startt, endt; rdtsc(startt); 1396 MarkOtherShowings(p); 1397 rdtsc(endt); 1398 mot2 += (endt - startt); moc2++; 1399 } 1400 else 1401 { 1402 uint64_t startt, endt; rdtsc(startt); 1403 MarkOtherShowings(p); 1404 rdtsc(endt); 1405 mot3 += (endt - startt); moc3++; 1406 } 1407 1105 1408 PrintRec(p, " +"); 1106 1409 } 1107 1410 else … … 1116 1419 i++; 1117 1420 if (i == worklist.end() || lastpri != (*i)->recpriority) 1118 1421 { 1422 uint64_t startt, endt; rdtsc(startt); 1119 1423 MoveHigherRecords(); 1424 rdtsc(endt); mht += (endt - startt); mhc++; 1120 1425 retrylist.clear(); 1121 1426 } 1122 1427 } 1428 1429 cout<<endl; 1430 VERBOSE(VB_IMPORTANT, "\nSchedulingNewRecords time report"); 1431 cout<<QString("MarkOtherShowings #1:%1 %2").arg(moc,4).arg(mot,12)<<endl; 1432 //cout<<QString("MarkOther... #2>=%0:%1 %2").arg(max_sz).arg(moc2,4).arg(mot2,12)<<endl; 1433 cout<<QString("MarkOtherShowings #2:%1 %2") 1434 .arg(moc2+moc3,4).arg(mot2+mot3,12)<<endl; 1435 cout<<QString("FindAnyConflict: %1 %2").arg(fac,4).arg(fat,12)<<endl; 1436 cout<<QString("MoveHigherRecords: %1 %2").arg(mhc,4).arg(mht,12)<<endl; 1437 cout<<endl; 1438 cout<<QString("OtherShowings >= %1").arg(max_sz)<<endl; 1439 QMap<QString,uint>::iterator it = othershow.begin(); 1440 for (; it != othershow.end(); ++it) 1441 cout<<QString("%1: %2").arg(it.key(),20).arg(*it, 5)<<endl; 1442 cout<<endl; 1123 1443 } 1124 1444 1125 1445 void Scheduler::MoveHigherRecords(bool move_this) 1126 1446 { 1447 VERBOSE(VB_IMPORTANT, "MoveHigherRecords("<<move_this<< 1448 ") retrylist.size(): "<<retrylist.size()); 1449 uint64_t mht = 0, mhc = 0; 1450 uint64_t mht2 = 0, mhc2 = 0; 1451 uint64_t mht3 = 0, mhc3 = 0; 1452 uint64_t bst = 0, bsc = 0; 1453 uint64_t mot = 0, moc = 0; 1454 uint64_t rst = 0, rsc = 0; 1455 1456 1457 uint64_t startt, endt; rdtsc(startt); 1458 1127 1459 RecIter i = retrylist.begin(); 1128 1460 for ( ; i != retrylist.end(); i++) 1129 1461 { … … 1131 1463 if (p->recstatus != rsUnknown) 1132 1464 continue; 1133 1465 1466 print_verbose_messages |= VB_SCHEDULE; 1134 1467 PrintRec(p, " ?"); 1468 print_verbose_messages &= ~VB_SCHEDULE; 1135 1469 1470 uint64_t startt, endt; rdtsc(startt); 1471 bool cont = false; 1136 1472 if (move_this && TryAnotherShowing(p)) 1473 cont = true;; 1474 rdtsc(endt); mht += (endt - startt); mhc++; 1475 if (cont) 1137 1476 continue; 1138 1477 1139 BackupRecStatus(); 1478 { 1479 uint64_t startt, endt; rdtsc(startt); 1480 BackupRecStatus(); 1481 rdtsc(endt); bst += (endt - startt); bsc++; 1482 } 1483 1140 1484 p->recstatus = rsWillRecord; 1141 1485 if (move_this) 1486 { 1487 uint64_t startt, endt; rdtsc(startt); 1142 1488 MarkOtherShowings(p); 1489 rdtsc(endt); mot += (endt - startt); moc++; 1490 } 1143 1491 1144 RecList cardlist; 1145 QMap<int, RecList>::const_iterator it = cardlistmap.begin(); 1146 for (; it != cardlistmap.end(); ++it) 1492 1493 RecList conflicts = FindAllConflict(conflictmap, p, false); 1494 RecList::iterator k = conflicts.begin(); 1495 for (; k != conflicts.end(); ++k) 1147 1496 { 1148 RecConstIter it2 = (*it).begin(); 1149 for (; it2 != (*it).end(); ++it2) 1150 cardlist.push_back(*it2); 1151 } 1152 1153 RecConstIter k = cardlist.begin(); 1154 for ( ; FindNextConflict(cardlist, p, k); k++) 1155 { 1497 uint64_t startt, endt; rdtsc(startt); 1156 1498 if ((p->recpriority < (*k)->recpriority && !schedMoveHigher && 1157 move_this) || !TryAnotherShowing(*k, !move_this))1499 move_this) || !TryAnotherShowing(*k, !move_this)) 1158 1500 { 1501 uint64_t startt, endt; rdtsc(startt); 1159 1502 RestoreRecStatus(); 1503 rdtsc(endt); rst += (endt - startt); rsc++; 1160 1504 break; 1161 1505 } 1506 rdtsc(endt); mht2 += (endt - startt); mhc2++; 1162 1507 } 1163 1508 1164 1509 if (move_this && p->recstatus == rsWillRecord) 1165 1510 PrintRec(p, " +"); 1166 1511 } 1512 rdtsc(endt); mht3 += (endt - startt); mhc3++; 1513 1514 cout<<QString("MHR1: %1 %2").arg(mhc,4).arg(mht,12)<<endl; 1515 cout<<QString("MHR2: %1 %2").arg(mhc2,4).arg(mht2,12)<<endl; 1516 cout<<QString("BRS: %1 %2").arg(bsc,4).arg(bst,12)<<endl; 1517 cout<<QString("RRS: %1 %2").arg(rsc,4).arg(rst,12)<<endl; 1518 cout<<QString("MOS: %1 %2").arg(moc,4).arg(mot,12)<<endl; 1519 cout<<QString("MHRT: %1 %2").arg(mhc3,4).arg(mht3,12)<<endl; 1167 1520 } 1168 1521 1169 1522 void Scheduler::PruneRedundants(void) … … 1522 1875 VERBOSE(VB_GENERAL, msg); 1523 1876 gContext->LogEntry("scheduler", LP_INFO, "Scheduled items", msg); 1524 1877 1878 unsigned long long itotal[4] = {0,0,0,0}; 1879 unsigned long long jtotal[4] = {0,0,0,0}; 1880 unsigned long long ktotal[4] = {0,0,0,0}; 1881 unsigned long long cnt[4] = {0,0,0,0}; 1882 uint imax[4] = {0,0,0,0}, jmax[4] = {0,0,0,0}, kmax[4] = {0,0,0,0}; 1883 for (uint i = 0; i < stats_i.size(); i++) 1884 { 1885 uint j = (stats_found[i]) ? 1 : 0; 1886 cnt[j]++; 1887 itotal[j] += stats_i[i]; 1888 imax[j] = max(imax[j], stats_i[i]); 1889 jtotal[j] += stats_j[i]; 1890 jmax[j] = max(jmax[j], stats_j[i]); 1891 ktotal[j] += stats_k[i]; 1892 kmax[j] = max(kmax[j], stats_k[i]); 1893 } 1894 1895 for (uint i = 0; i < stats_all_i.size(); i++) 1896 { 1897 uint j = 2 + (stats_all_found[i]) ? 1 : 0; 1898 cnt[j] += stats_all_found[i]; 1899 itotal[j] += stats_all_i[i]; 1900 imax[j] = max(imax[j], stats_all_i[i]); 1901 jtotal[j] += stats_all_j[i]; 1902 jmax[j] = max(jmax[j], stats_all_j[i]); 1903 ktotal[j] += stats_all_k[i]; 1904 kmax[j] = max(kmax[j], stats_all_k[i]); 1905 } 1906 1907 for (uint i = 0; i < 4; i++) 1908 { 1909 VERBOSE(VB_IMPORTANT, 1910 QString("avg i: %1 j: %2, k: %3 max i: %4 j: %5 k: %6") 1911 .arg((double)itotal[i] / (double)cnt[i]) 1912 .arg((double)jtotal[i] / (double)cnt[i]) 1913 .arg((double)ktotal[i] / (double)cnt[i]) 1914 .arg(imax[i]).arg(jmax[i]).arg(kmax[i])); 1915 } 1916 1525 1917 fsInfoCacheFillTime = QDateTime::currentDateTime().addSecs(-1000); 1526 1918 1527 1919 lastupdate = curtime;