Mercurial > hg > svcore
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 |
