comparison data/fft/FFTDataServer.cpp @ 678:948271d124ac

Make more (though still not entirely) robust in the face of running out of disc space
author Chris Cannam
date Thu, 14 Apr 2011 15:20:27 +0100
parents dfc4dd561bb6
children b4a8d8221eaf
comparison
equal deleted inserted replaced
677:ce73529405e4 678:948271d124ac
812 FFTCache::Rectangular, 812 FFTCache::Rectangular,
813 width, m_height); 813 width, m_height);
814 814
815 success = true; 815 success = true;
816 816
817 } catch (std::exception e) { 817 } catch (std::exception &e) {
818 818
819 delete cb->fileCacheWriter; 819 delete cb->fileCacheWriter;
820 cb->fileCacheWriter = 0; 820 cb->fileCacheWriter = 0;
821 821
822 std::cerr << "ERROR: Failed to construct disc cache for FFT data: " 822 std::cerr << "ERROR: Failed to construct disc cache for FFT data: "
823 << e.what() << std::endl; 823 << e.what() << std::endl;
824
825 throw;
824 } 826 }
825 } 827 }
826 828
827 m_cacheVectorLock.lockForWrite(); 829 m_cacheVectorLock.lockForWrite();
828 830
849 851
850 try { 852 try {
851 853
852 cb->fileCacheReader[me] = new FFTFileCacheReader(cb->fileCacheWriter); 854 cb->fileCacheReader[me] = new FFTFileCacheReader(cb->fileCacheWriter);
853 855
854 } catch (std::exception e) { 856 } catch (std::exception &e) {
855 857
856 delete cb->fileCacheReader[me]; 858 delete cb->fileCacheReader[me];
857 cb->fileCacheReader.erase(me); 859 cb->fileCacheReader.erase(me);
858 860
859 std::cerr << "ERROR: Failed to construct disc cache reader for FFT data: " 861 std::cerr << "ERROR: Failed to construct disc cache reader for FFT data: "
887 { 889 {
888 Profiler profiler("FFTDataServer::getMagnitudeAt", false); 890 Profiler profiler("FFTDataServer::getMagnitudeAt", false);
889 891
890 if (x >= m_width || y >= m_height) return 0; 892 if (x >= m_width || y >= m_height) return 0;
891 893
892 size_t col; 894 float val = 0;
893 FFTCacheReader *cache = getCacheReader(x, col); 895
894 if (!cache) return 0; 896 try {
895 897 size_t col;
896 //!!! n.b. can throw 898 FFTCacheReader *cache = getCacheReader(x, col);
897 if (!cache->haveSetColumnAt(col)) { 899 if (!cache) return 0;
898 Profiler profiler("FFTDataServer::getMagnitudeAt: filling"); 900
899 #ifdef DEBUG_FFT_SERVER 901 if (!cache->haveSetColumnAt(col)) {
900 std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn(" 902 Profiler profiler("FFTDataServer::getMagnitudeAt: filling");
903 #ifdef DEBUG_FFT_SERVER
904 std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn("
901 << x << ")" << std::endl; 905 << x << ")" << std::endl;
902 #endif 906 #endif
903 fillColumn(x); 907 fillColumn(x);
904 } 908 }
905 return cache->getMagnitudeAt(col, y); 909
910 val = cache->getMagnitudeAt(col, y);
911
912 } catch (std::exception &e) {
913 m_error = e.what();
914 }
915
916 return val;
906 } 917 }
907 918
908 bool 919 bool
909 FFTDataServer::getMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) 920 FFTDataServer::getMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step)
910 { 921 {
916 if (count == 0) count = (m_height - minbin) / step; 927 if (count == 0) count = (m_height - minbin) / step;
917 else if (minbin + count * step > m_height) { 928 else if (minbin + count * step > m_height) {
918 count = (m_height - minbin) / step; 929 count = (m_height - minbin) / step;
919 } 930 }
920 931
921 size_t col; 932 try {
922 FFTCacheReader *cache = getCacheReader(x, col); 933 size_t col;
923 if (!cache) return false; 934 FFTCacheReader *cache = getCacheReader(x, col);
924 935 if (!cache) return false;
925 //!!! n.b. can throw 936
926 if (!cache->haveSetColumnAt(col)) { 937 if (!cache->haveSetColumnAt(col)) {
927 Profiler profiler("FFTDataServer::getMagnitudesAt: filling"); 938 Profiler profiler("FFTDataServer::getMagnitudesAt: filling");
928 fillColumn(x); 939 fillColumn(x);
929 } 940 }
930 941
931 cache->getMagnitudesAt(col, values, minbin, count, step); 942 cache->getMagnitudesAt(col, values, minbin, count, step);
943
944 } catch (std::exception &e) {
945 m_error = e.what();
946 return false;
947 }
932 948
933 return true; 949 return true;
934 } 950 }
935 951
936 float 952 float
938 { 954 {
939 Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt", false); 955 Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt", false);
940 956
941 if (x >= m_width || y >= m_height) return 0; 957 if (x >= m_width || y >= m_height) return 0;
942 958
943 size_t col; 959 float val = 0;
944 FFTCacheReader *cache = getCacheReader(x, col); 960
945 if (!cache) return 0; 961 try {
946 962
947 //!!! n.b. can throw 963 size_t col;
948 if (!cache->haveSetColumnAt(col)) { 964 FFTCacheReader *cache = getCacheReader(x, col);
949 Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt: filling"); 965 if (!cache) return 0;
950 fillColumn(x); 966
951 } 967 if (!cache->haveSetColumnAt(col)) {
952 return cache->getNormalizedMagnitudeAt(col, y); 968 Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt: filling");
969 fillColumn(x);
970 }
971 val = cache->getNormalizedMagnitudeAt(col, y);
972
973 } catch (std::exception &e) {
974 m_error = e.what();
975 }
976
977 return val;
953 } 978 }
954 979
955 bool 980 bool
956 FFTDataServer::getNormalizedMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) 981 FFTDataServer::getNormalizedMagnitudesAt(size_t x, float *values, size_t minbin, size_t count, size_t step)
957 { 982 {
963 if (count == 0) count = (m_height - minbin) / step; 988 if (count == 0) count = (m_height - minbin) / step;
964 else if (minbin + count * step > m_height) { 989 else if (minbin + count * step > m_height) {
965 count = (m_height - minbin) / step; 990 count = (m_height - minbin) / step;
966 } 991 }
967 992
968 size_t col; 993 try {
969 FFTCacheReader *cache = getCacheReader(x, col); 994
970 if (!cache) return false; 995 size_t col;
971 996 FFTCacheReader *cache = getCacheReader(x, col);
972 //!!! n.b. can throw 997 if (!cache) return false;
973 if (!cache->haveSetColumnAt(col)) { 998
974 Profiler profiler("FFTDataServer::getNormalizedMagnitudesAt: filling"); 999 if (!cache->haveSetColumnAt(col)) {
975 fillColumn(x); 1000 Profiler profiler("FFTDataServer::getNormalizedMagnitudesAt: filling");
976 } 1001 fillColumn(x);
977 1002 }
978 for (size_t i = 0; i < count; ++i) { 1003
979 values[i] = cache->getNormalizedMagnitudeAt(col, i * step + minbin); 1004 for (size_t i = 0; i < count; ++i) {
1005 values[i] = cache->getNormalizedMagnitudeAt(col, i * step + minbin);
1006 }
1007
1008 } catch (std::exception &e) {
1009 m_error = e.what();
1010 return false;
980 } 1011 }
981 1012
982 return true; 1013 return true;
983 } 1014 }
984 1015
987 { 1018 {
988 Profiler profiler("FFTDataServer::getMaximumMagnitudeAt", false); 1019 Profiler profiler("FFTDataServer::getMaximumMagnitudeAt", false);
989 1020
990 if (x >= m_width) return 0; 1021 if (x >= m_width) return 0;
991 1022
992 size_t col; 1023 float val = 0;
993 FFTCacheReader *cache = getCacheReader(x, col); 1024
994 if (!cache) return 0; 1025 try {
995 1026
996 //!!! n.b. can throw 1027 size_t col;
997 if (!cache->haveSetColumnAt(col)) { 1028 FFTCacheReader *cache = getCacheReader(x, col);
998 Profiler profiler("FFTDataServer::getMaximumMagnitudeAt: filling"); 1029 if (!cache) return 0;
999 fillColumn(x); 1030
1000 } 1031 if (!cache->haveSetColumnAt(col)) {
1001 return cache->getMaximumMagnitudeAt(col); 1032 Profiler profiler("FFTDataServer::getMaximumMagnitudeAt: filling");
1033 fillColumn(x);
1034 }
1035 val = cache->getMaximumMagnitudeAt(col);
1036
1037 } catch (std::exception &e) {
1038 m_error = e.what();
1039 }
1040
1041 return val;
1002 } 1042 }
1003 1043
1004 float 1044 float
1005 FFTDataServer::getPhaseAt(size_t x, size_t y) 1045 FFTDataServer::getPhaseAt(size_t x, size_t y)
1006 { 1046 {
1007 Profiler profiler("FFTDataServer::getPhaseAt", false); 1047 Profiler profiler("FFTDataServer::getPhaseAt", false);
1008 1048
1009 if (x >= m_width || y >= m_height) return 0; 1049 if (x >= m_width || y >= m_height) return 0;
1010 1050
1011 size_t col; 1051 float val = 0;
1012 FFTCacheReader *cache = getCacheReader(x, col); 1052
1013 if (!cache) return 0; 1053 try {
1014 1054
1015 //!!! n.b. can throw 1055 size_t col;
1016 if (!cache->haveSetColumnAt(col)) { 1056 FFTCacheReader *cache = getCacheReader(x, col);
1017 Profiler profiler("FFTDataServer::getPhaseAt: filling"); 1057 if (!cache) return 0;
1018 fillColumn(x); 1058
1019 } 1059 if (!cache->haveSetColumnAt(col)) {
1020 return cache->getPhaseAt(col, y); 1060 Profiler profiler("FFTDataServer::getPhaseAt: filling");
1061 fillColumn(x);
1062 }
1063 val = cache->getPhaseAt(col, y);
1064
1065 } catch (std::exception &e) {
1066 m_error = e.what();
1067 }
1068
1069 return val;
1021 } 1070 }
1022 1071
1023 bool 1072 bool
1024 FFTDataServer::getPhasesAt(size_t x, float *values, size_t minbin, size_t count, size_t step) 1073 FFTDataServer::getPhasesAt(size_t x, float *values, size_t minbin, size_t count, size_t step)
1025 { 1074 {
1031 if (count == 0) count = (m_height - minbin) / step; 1080 if (count == 0) count = (m_height - minbin) / step;
1032 else if (minbin + count * step > m_height) { 1081 else if (minbin + count * step > m_height) {
1033 count = (m_height - minbin) / step; 1082 count = (m_height - minbin) / step;
1034 } 1083 }
1035 1084
1036 size_t col; 1085 try {
1037 FFTCacheReader *cache = getCacheReader(x, col); 1086
1038 if (!cache) return false; 1087 size_t col;
1039 1088 FFTCacheReader *cache = getCacheReader(x, col);
1040 //!!! n.b. can throw 1089 if (!cache) return false;
1041 if (!cache->haveSetColumnAt(col)) { 1090
1042 Profiler profiler("FFTDataServer::getPhasesAt: filling"); 1091 if (!cache->haveSetColumnAt(col)) {
1043 fillColumn(x); 1092 Profiler profiler("FFTDataServer::getPhasesAt: filling");
1044 } 1093 fillColumn(x);
1045 1094 }
1046 for (size_t i = 0; i < count; ++i) { 1095
1047 values[i] = cache->getPhaseAt(col, i * step + minbin); 1096 for (size_t i = 0; i < count; ++i) {
1097 values[i] = cache->getPhaseAt(col, i * step + minbin);
1098 }
1099
1100 } catch (std::exception &e) {
1101 m_error = e.what();
1102 return false;
1048 } 1103 }
1049 1104
1050 return true; 1105 return true;
1051 } 1106 }
1052 1107
1059 real = 0; 1114 real = 0;
1060 imaginary = 0; 1115 imaginary = 0;
1061 return; 1116 return;
1062 } 1117 }
1063 1118
1064 size_t col; 1119 try {
1065 FFTCacheReader *cache = getCacheReader(x, col); 1120
1066 1121 size_t col;
1067 if (!cache) { 1122 FFTCacheReader *cache = getCacheReader(x, col);
1068 real = 0; 1123
1069 imaginary = 0; 1124 if (!cache) {
1070 return; 1125 real = 0;
1071 } 1126 imaginary = 0;
1072 1127 return;
1073 //!!! n.b. can throw 1128 }
1074 if (!cache->haveSetColumnAt(col)) { 1129
1075 Profiler profiler("FFTDataServer::getValuesAt: filling"); 1130 if (!cache->haveSetColumnAt(col)) {
1076 #ifdef DEBUG_FFT_SERVER 1131 Profiler profiler("FFTDataServer::getValuesAt: filling");
1077 std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl; 1132 #ifdef DEBUG_FFT_SERVER
1078 #endif 1133 std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl;
1079 fillColumn(x); 1134 #endif
1080 } 1135 fillColumn(x);
1081 1136 }
1082 cache->getValuesAt(col, y, real, imaginary); 1137
1138 cache->getValuesAt(col, y, real, imaginary);
1139
1140 } catch (std::exception &e) {
1141 m_error = e.what();
1142 }
1083 } 1143 }
1084 1144
1085 bool 1145 bool
1086 FFTDataServer::getValuesAt(size_t x, float *reals, float *imaginaries, size_t minbin, size_t count, size_t step) 1146 FFTDataServer::getValuesAt(size_t x, float *reals, float *imaginaries, size_t minbin, size_t count, size_t step)
1087 { 1147 {
1093 if (count == 0) count = (m_height - minbin) / step; 1153 if (count == 0) count = (m_height - minbin) / step;
1094 else if (minbin + count * step > m_height) { 1154 else if (minbin + count * step > m_height) {
1095 count = (m_height - minbin) / step; 1155 count = (m_height - minbin) / step;
1096 } 1156 }
1097 1157
1098 size_t col; 1158 try {
1099 FFTCacheReader *cache = getCacheReader(x, col); 1159
1100 if (!cache) return false; 1160 size_t col;
1101 1161 FFTCacheReader *cache = getCacheReader(x, col);
1102 //!!! n.b. can throw 1162 if (!cache) return false;
1103 if (!cache->haveSetColumnAt(col)) { 1163
1104 Profiler profiler("FFTDataServer::getValuesAt: filling"); 1164 if (!cache->haveSetColumnAt(col)) {
1105 fillColumn(x); 1165 Profiler profiler("FFTDataServer::getValuesAt: filling");
1106 } 1166 fillColumn(x);
1107 1167 }
1108 for (size_t i = 0; i < count; ++i) { 1168
1109 cache->getValuesAt(col, i * step + minbin, reals[i], imaginaries[i]); 1169 for (size_t i = 0; i < count; ++i) {
1170 cache->getValuesAt(col, i * step + minbin, reals[i], imaginaries[i]);
1171 }
1172
1173 } catch (std::exception &e) {
1174 m_error = e.what();
1175 return false;
1110 } 1176 }
1111 1177
1112 return true; 1178 return true;
1113 } 1179 }
1114 1180
1130 } 1196 }
1131 */ 1197 */
1132 return false; 1198 return false;
1133 } 1199 }
1134 1200
1135 size_t col; 1201 try {
1136 FFTCacheReader *cache = getCacheReader(x, col); 1202
1137 if (!cache) return true; 1203 size_t col;
1138 1204 FFTCacheReader *cache = getCacheReader(x, col);
1139 //!!! n.b. can throw 1205 if (!cache) return true;
1140 return cache->haveSetColumnAt(col); 1206
1207 return cache->haveSetColumnAt(col);
1208
1209 } catch (std::exception &e) {
1210 m_error = e.what();
1211 return false;
1212 }
1141 } 1213 }
1142 1214
1143 void 1215 void
1144 FFTDataServer::fillColumn(size_t x) 1216 FFTDataServer::fillColumn(size_t x)
1145 { 1217 {
1305 1377
1306 void 1378 void
1307 FFTDataServer::fillComplete() 1379 FFTDataServer::fillComplete()
1308 { 1380 {
1309 for (int i = 0; i < int(m_caches.size()); ++i) { 1381 for (int i = 0; i < int(m_caches.size()); ++i) {
1382 if (!m_caches[i]) continue;
1310 if (m_caches[i]->memoryCache) { 1383 if (m_caches[i]->memoryCache) {
1311 m_caches[i]->memoryCache->allColumnsWritten(); 1384 m_caches[i]->memoryCache->allColumnsWritten();
1312 } 1385 }
1313 if (m_caches[i]->fileCacheWriter) { 1386 if (m_caches[i]->fileCacheWriter) {
1314 m_caches[i]->fileCacheWriter->allColumnsWritten(); 1387 m_caches[i]->fileCacheWriter->allColumnsWritten();
1315 } 1388 }
1316 } 1389 }
1390 }
1391
1392 QString
1393 FFTDataServer::getError() const
1394 {
1395 if (m_error != "") return m_error;
1396 else if (m_fillThread) return m_fillThread->getError();
1397 else return "";
1317 } 1398 }
1318 1399
1319 size_t 1400 size_t
1320 FFTDataServer::getFillCompletion() const 1401 FFTDataServer::getFillCompletion() const
1321 { 1402 {
1390 1471
1391 if (m_fillFrom > start) { 1472 if (m_fillFrom > start) {
1392 1473
1393 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) { 1474 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) {
1394 1475
1395 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); 1476 try {
1477 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement));
1478 } catch (std::exception &e) {
1479 std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl;
1480 m_error = e.what();
1481 m_server.fillComplete();
1482 m_completion = 100;
1483 m_extent = end;
1484 return;
1485 }
1396 1486
1397 if (m_server.m_exiting) return; 1487 if (m_server.m_exiting) return;
1398 1488
1399 while (m_server.m_suspended) { 1489 while (m_server.m_suspended) {
1400 #ifdef DEBUG_FFT_SERVER 1490 #ifdef DEBUG_FFT_SERVER
1430 1520
1431 size_t baseCompletion = m_completion; 1521 size_t baseCompletion = m_completion;
1432 1522
1433 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) { 1523 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) {
1434 1524
1435 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); 1525 try {
1526 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement));
1527 } catch (std::exception &e) {
1528 std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl;
1529 m_error = e.what();
1530 m_server.fillComplete();
1531 m_completion = 100;
1532 m_extent = end;
1533 return;
1534 }
1436 1535
1437 if (m_server.m_exiting) return; 1536 if (m_server.m_exiting) return;
1438 1537
1439 while (m_server.m_suspended) { 1538 while (m_server.m_suspended) {
1440 #ifdef DEBUG_FFT_SERVER 1539 #ifdef DEBUG_FFT_SERVER