annotate base/StorageAdviser.cpp @ 1394:9ef1cc26024c

Add Range01 normalisation method to ColumnOp. This is the normalisation that is actually used in the Colour 3D Plot layer historically when column normalisation is enabled (not Max1 after all).
author Chris Cannam
date Tue, 28 Feb 2017 14:04:16 +0000
parents adbd16d2c1e8
children 91231350ee22
rev   line source
Chris@168 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@168 2
Chris@168 3 /*
Chris@168 4 Sonic Visualiser
Chris@168 5 An audio file viewer and annotation editor.
Chris@168 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 QMUL.
Chris@168 8
Chris@168 9 This program is free software; you can redistribute it and/or
Chris@168 10 modify it under the terms of the GNU General Public License as
Chris@168 11 published by the Free Software Foundation; either version 2 of the
Chris@168 12 License, or (at your option) any later version. See the file
Chris@168 13 COPYING included with this distribution for more information.
Chris@168 14 */
Chris@168 15
Chris@168 16 #include "StorageAdviser.h"
Chris@168 17
Chris@168 18 #include "Exceptions.h"
Chris@168 19 #include "TempDirectory.h"
Chris@168 20
Chris@168 21 #include "system/System.h"
Chris@168 22
Chris@168 23 #include <iostream>
Chris@168 24
Chris@1276 25 QString
Chris@1276 26 StorageAdviser::criteriaToString(int criteria)
Chris@1276 27 {
Chris@1276 28 QStringList labels;
Chris@1276 29 if (criteria & SpeedCritical) labels.push_back("SpeedCritical");
Chris@1276 30 if (criteria & PrecisionCritical) labels.push_back("PrecisionCritical");
Chris@1276 31 if (criteria & LongRetentionLikely) labels.push_back("LongRetentionLikely");
Chris@1276 32 if (criteria & FrequentLookupLikely) labels.push_back("FrequentLookupLikely");
Chris@1276 33 if (labels.empty()) return "None";
Chris@1276 34 else return labels.join("+");
Chris@1276 35 }
Chris@1276 36
Chris@1276 37 QString
Chris@1276 38 StorageAdviser::recommendationToString(int recommendation)
Chris@1276 39 {
Chris@1276 40 QStringList labels;
Chris@1276 41 if (recommendation & UseMemory) labels.push_back("UseMemory");
Chris@1276 42 if (recommendation & PreferMemory) labels.push_back("PreferMemory");
Chris@1276 43 if (recommendation & PreferDisc) labels.push_back("PreferDisc");
Chris@1276 44 if (recommendation & UseDisc) labels.push_back("UseDisc");
Chris@1276 45 if (recommendation & ConserveSpace) labels.push_back("ConserveSpace");
Chris@1276 46 if (recommendation & UseAsMuchAsYouLike) labels.push_back("UseAsMuchAsYouLike");
Chris@1276 47 if (labels.empty()) return "None";
Chris@1276 48 else return labels.join("+");
Chris@1276 49 }
Chris@1276 50
Chris@1276 51 QString
Chris@1276 52 StorageAdviser::storageStatusToString(StorageStatus status)
Chris@1276 53 {
Chris@1276 54 if (status == Insufficient) return "Insufficient";
Chris@1276 55 if (status == Marginal) return "Marginal";
Chris@1276 56 if (status == Sufficient) return "Sufficient";
Chris@1276 57 return "Unknown";
Chris@1276 58 }
Chris@374 59
Chris@1038 60 size_t StorageAdviser::m_discPlanned = 0;
Chris@1038 61 size_t StorageAdviser::m_memoryPlanned = 0;
Chris@205 62
Chris@168 63 StorageAdviser::Recommendation
Chris@411 64 StorageAdviser::m_baseRecommendation = StorageAdviser::NoRecommendation;
Chris@411 65
Chris@411 66 StorageAdviser::Recommendation
Chris@168 67 StorageAdviser::recommend(Criteria criteria,
Chris@1038 68 size_t minimumSize,
Chris@1038 69 size_t maximumSize)
Chris@168 70 {
Chris@1276 71 SVDEBUG << "StorageAdviser::recommend: criteria " << criteria
Chris@1276 72 << " (" + criteriaToString(criteria) + ")"
Chris@1276 73 << ", minimumSize " << minimumSize
Chris@1276 74 << ", maximumSize " << maximumSize << endl;
Chris@170 75
Chris@411 76 if (m_baseRecommendation != NoRecommendation) {
Chris@1276 77 SVDEBUG << "StorageAdviser::recommend: Returning fixed recommendation "
Chris@1276 78 << m_baseRecommendation << " ("
Chris@1276 79 << recommendationToString(m_baseRecommendation) << ")" << endl;
Chris@411 80 return m_baseRecommendation; // for now
Chris@411 81 }
Chris@411 82
Chris@541 83 QString path;
Chris@541 84 try {
Chris@541 85 path = TempDirectory::getInstance()->getPath();
Chris@541 86 } catch (std::exception e) {
Chris@1276 87 SVDEBUG << "StorageAdviser::recommend: ERROR: Failed to get temporary directory path: " << e.what() << endl;
Chris@1276 88 int r = UseMemory | ConserveSpace;
Chris@1276 89 SVDEBUG << "StorageAdviser: returning fallback " << r
Chris@1276 90 << " (" << recommendationToString(r) << ")" << endl;
Chris@1276 91 return Recommendation(r);
Chris@541 92 }
Chris@1038 93 ssize_t discFree = GetDiscSpaceMBAvailable(path.toLocal8Bit());
Chris@1038 94 ssize_t memoryFree, memoryTotal;
Chris@170 95 GetRealMemoryMBAvailable(memoryFree, memoryTotal);
Chris@168 96
Chris@1276 97 SVDEBUG << "StorageAdviser: disc space: " << discFree
Chris@1276 98 << "M, memory free: " << memoryFree
Chris@1276 99 << "M, memory total: " << memoryTotal << "M" << endl;
Chris@1276 100 SVDEBUG << "StorageAdviser: disc planned: " << (m_discPlanned / 1024)
Chris@1276 101 << "K, memory planned: " << (m_memoryPlanned / 1024) << "K" << endl;
Chris@1276 102 SVDEBUG << "StorageAdviser: min requested: " << minimumSize
Chris@1276 103 << "K, max requested: " << maximumSize << "K" << endl;
Chris@1276 104
Chris@1038 105 if (discFree > ssize_t(m_discPlanned / 1024 + 1)) {
Chris@205 106 discFree -= m_discPlanned / 1024 + 1;
Chris@205 107 } else if (discFree > 0) { // can also be -1 for unknown
Chris@205 108 discFree = 0;
Chris@205 109 }
Chris@205 110
Chris@1038 111 if (memoryFree > ssize_t(m_memoryPlanned / 1024 + 1)) {
Chris@205 112 memoryFree -= m_memoryPlanned / 1024 + 1;
Chris@205 113 } else if (memoryFree > 0) { // can also be -1 for unknown
Chris@205 114 memoryFree = 0;
Chris@205 115 }
Chris@205 116
Chris@192 117 //!!! We have a potentially serious problem here if multiple
Chris@192 118 //recommendations are made in advance of any of the resulting
Chris@192 119 //allocations, as the allocations that have been recommended for
Chris@192 120 //won't be taken into account in subsequent recommendations.
Chris@192 121
Chris@170 122 StorageStatus memoryStatus = Unknown;
Chris@170 123 StorageStatus discStatus = Unknown;
Chris@170 124
Chris@1038 125 ssize_t minmb = ssize_t(minimumSize / 1024 + 1);
Chris@1038 126 ssize_t maxmb = ssize_t(maximumSize / 1024 + 1);
Chris@170 127
Chris@170 128 if (memoryFree == -1) memoryStatus = Unknown;
Chris@1103 129 else if (memoryFree < memoryTotal / 3 && memoryFree < 512) memoryStatus = Insufficient;
Chris@170 130 else if (minmb > (memoryFree * 3) / 4) memoryStatus = Insufficient;
Chris@170 131 else if (maxmb > (memoryFree * 3) / 4) memoryStatus = Marginal;
Chris@170 132 else if (minmb > (memoryFree / 3)) memoryStatus = Marginal;
Chris@170 133 else if (memoryTotal == -1 ||
Chris@170 134 minmb > (memoryTotal / 10)) memoryStatus = Marginal;
Chris@170 135 else memoryStatus = Sufficient;
Chris@170 136
Chris@170 137 if (discFree == -1) discStatus = Unknown;
Chris@170 138 else if (minmb > (discFree * 3) / 4) discStatus = Insufficient;
Chris@173 139 else if (maxmb > (discFree / 4)) discStatus = Marginal;
Chris@173 140 else if (minmb > (discFree / 10)) discStatus = Marginal;
Chris@170 141 else discStatus = Sufficient;
Chris@170 142
Chris@1276 143 SVDEBUG << "StorageAdviser: memory status: " << memoryStatus
Chris@1276 144 << " (" << storageStatusToString(memoryStatus) << ")"
Chris@1276 145 << ", disc status " << discStatus
Chris@1276 146 << " (" << storageStatusToString(discStatus) << ")" << endl;
Chris@170 147
Chris@170 148 int recommendation = NoRecommendation;
Chris@170 149
Chris@170 150 if (memoryStatus == Insufficient || memoryStatus == Unknown) {
Chris@170 151
Chris@170 152 recommendation |= UseDisc;
Chris@170 153
Chris@170 154 if (discStatus == Insufficient && minmb > discFree) {
Chris@170 155 throw InsufficientDiscSpace(path, minmb, discFree);
Chris@170 156 }
Chris@170 157
Chris@170 158 if (discStatus == Insufficient || discStatus == Marginal) {
Chris@170 159 recommendation |= ConserveSpace;
Chris@170 160 } else if (discStatus == Unknown && !(criteria & PrecisionCritical)) {
Chris@170 161 recommendation |= ConserveSpace;
Chris@170 162 } else {
Chris@170 163 recommendation |= UseAsMuchAsYouLike;
Chris@170 164 }
Chris@170 165
Chris@170 166 } else if (memoryStatus == Marginal) {
Chris@170 167
Chris@170 168 if (((criteria & SpeedCritical) ||
Chris@170 169 (criteria & FrequentLookupLikely)) &&
Chris@170 170 !(criteria & PrecisionCritical) &&
Chris@170 171 !(criteria & LongRetentionLikely)) {
Chris@170 172
Chris@170 173 // requirements suggest a preference for memory
Chris@170 174
Chris@170 175 if (discStatus != Insufficient) {
Chris@170 176 recommendation |= PreferMemory;
Chris@170 177 } else {
Chris@170 178 recommendation |= UseMemory;
Chris@170 179 }
Chris@170 180
Chris@170 181 recommendation |= ConserveSpace;
Chris@170 182
Chris@170 183 } else {
Chris@170 184
Chris@170 185 if (discStatus == Insufficient) {
Chris@170 186 recommendation |= (UseMemory | ConserveSpace);
Chris@170 187 } else if (discStatus == Marginal) {
Chris@170 188 recommendation |= (PreferMemory | ConserveSpace);
Chris@170 189 } else if (discStatus == Unknown) {
Chris@170 190 recommendation |= (PreferDisc | ConserveSpace);
Chris@170 191 } else {
Chris@170 192 recommendation |= (UseDisc | UseAsMuchAsYouLike);
Chris@170 193 }
Chris@170 194 }
Chris@170 195
Chris@170 196 } else {
Chris@170 197
Chris@170 198 if (discStatus == Insufficient) {
Chris@170 199 recommendation |= (UseMemory | ConserveSpace);
Chris@170 200 } else if (discStatus != Sufficient) {
Chris@170 201 recommendation |= (PreferMemory | ConserveSpace);
Chris@170 202 } else {
Chris@170 203
Chris@170 204 if ((criteria & SpeedCritical) ||
Chris@170 205 (criteria & FrequentLookupLikely)) {
Chris@170 206 recommendation |= PreferMemory;
Chris@170 207 if (criteria & PrecisionCritical) {
Chris@170 208 recommendation |= UseAsMuchAsYouLike;
Chris@170 209 } else {
Chris@170 210 recommendation |= ConserveSpace;
Chris@170 211 }
Chris@170 212 } else {
Chris@170 213 recommendation |= PreferDisc;
Chris@170 214 recommendation |= UseAsMuchAsYouLike;
Chris@170 215 }
Chris@170 216 }
Chris@170 217 }
Chris@170 218
Chris@1276 219 SVDEBUG << "StorageAdviser: returning recommendation " << recommendation
Chris@1276 220 << " (" << recommendationToString(recommendation) << ")" << endl;
Chris@1098 221
Chris@170 222 return Recommendation(recommendation);
Chris@168 223 }
Chris@168 224
Chris@205 225 void
Chris@1038 226 StorageAdviser::notifyPlannedAllocation(AllocationArea area, size_t size)
Chris@205 227 {
Chris@205 228 if (area == MemoryAllocation) m_memoryPlanned += size;
Chris@205 229 else if (area == DiscAllocation) m_discPlanned += size;
Chris@1276 230 SVDEBUG << "StorageAdviser: storage planned up: now memory: " << m_memoryPlanned << ", disc "
Chris@1276 231 << m_discPlanned << endl;
Chris@205 232 }
Chris@205 233
Chris@205 234 void
Chris@1038 235 StorageAdviser::notifyDoneAllocation(AllocationArea area, size_t size)
Chris@205 236 {
Chris@205 237 if (area == MemoryAllocation) {
Chris@205 238 if (m_memoryPlanned > size) m_memoryPlanned -= size;
Chris@205 239 else m_memoryPlanned = 0;
Chris@205 240 } else if (area == DiscAllocation) {
Chris@205 241 if (m_discPlanned > size) m_discPlanned -= size;
Chris@205 242 else m_discPlanned = 0;
Chris@205 243 }
Chris@1276 244 SVDEBUG << "StorageAdviser: storage planned down: now memory: " << m_memoryPlanned << ", disc "
Chris@1276 245 << m_discPlanned << endl;
Chris@205 246 }
Chris@205 247
Chris@411 248 void
Chris@411 249 StorageAdviser::setFixedRecommendation(Recommendation recommendation)
Chris@411 250 {
Chris@411 251 m_baseRecommendation = recommendation;
Chris@411 252 }
Chris@411 253