00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "StorageAdviser.h"
00017
00018 #include "Exceptions.h"
00019 #include "TempDirectory.h"
00020
00021 #include "system/System.h"
00022
00023 #include <iostream>
00024
00025
00026
00027 long StorageAdviser::m_discPlanned = 0;
00028 long StorageAdviser::m_memoryPlanned = 0;
00029
00030 StorageAdviser::Recommendation
00031 StorageAdviser::recommend(Criteria criteria,
00032 int minimumSize,
00033 int maximumSize)
00034 {
00035 #ifdef DEBUG_STORAGE_ADVISER
00036 std::cerr << "StorageAdviser::recommend: Criteria " << criteria
00037 << ", minimumSize " << minimumSize
00038 << ", maximumSize " << maximumSize << std::endl;
00039 #endif
00040
00041 QString path = TempDirectory::getInstance()->getPath();
00042 int discFree = GetDiscSpaceMBAvailable(path.toLocal8Bit());
00043 int memoryFree, memoryTotal;
00044 GetRealMemoryMBAvailable(memoryFree, memoryTotal);
00045
00046 if (discFree > m_discPlanned / 1024 + 1) {
00047 discFree -= m_discPlanned / 1024 + 1;
00048 } else if (discFree > 0) {
00049 discFree = 0;
00050 }
00051
00052 if (memoryFree > m_memoryPlanned / 1024 + 1) {
00053 memoryFree -= m_memoryPlanned / 1024 + 1;
00054 } else if (memoryFree > 0) {
00055 memoryFree = 0;
00056 }
00057
00058 #ifdef DEBUG_STORAGE_ADVISER
00059 std::cerr << "Disc space: " << discFree << ", memory free: " << memoryFree << ", memory total: " << memoryTotal << ", min " << minimumSize << ", max " << maximumSize << std::endl;
00060 #endif
00061
00063
00064
00065
00066
00067 enum StorageStatus {
00068 Unknown,
00069 Insufficient,
00070 Marginal,
00071 Sufficient
00072 };
00073
00074 StorageStatus memoryStatus = Unknown;
00075 StorageStatus discStatus = Unknown;
00076
00077 int minmb = minimumSize / 1024 + 1;
00078 int maxmb = maximumSize / 1024 + 1;
00079
00080 if (memoryFree == -1) memoryStatus = Unknown;
00081 else if (minmb > (memoryFree * 3) / 4) memoryStatus = Insufficient;
00082 else if (maxmb > (memoryFree * 3) / 4) memoryStatus = Marginal;
00083 else if (minmb > (memoryFree / 3)) memoryStatus = Marginal;
00084 else if (memoryTotal == -1 ||
00085 minmb > (memoryTotal / 10)) memoryStatus = Marginal;
00086 else if (memoryFree < memoryTotal / 4) memoryStatus = Marginal;
00087 else memoryStatus = Sufficient;
00088
00089 if (discFree == -1) discStatus = Unknown;
00090 else if (minmb > (discFree * 3) / 4) discStatus = Insufficient;
00091 else if (maxmb > (discFree / 4)) discStatus = Marginal;
00092 else if (minmb > (discFree / 10)) discStatus = Marginal;
00093 else discStatus = Sufficient;
00094
00095 #ifdef DEBUG_STORAGE_ADVISER
00096 std::cerr << "Memory status: " << memoryStatus << ", disc status "
00097 << discStatus << std::endl;
00098 #endif
00099
00100 int recommendation = NoRecommendation;
00101
00102 if (memoryStatus == Insufficient || memoryStatus == Unknown) {
00103
00104 recommendation |= UseDisc;
00105
00106 if (discStatus == Insufficient && minmb > discFree) {
00107 throw InsufficientDiscSpace(path, minmb, discFree);
00108 }
00109
00110 if (discStatus == Insufficient || discStatus == Marginal) {
00111 recommendation |= ConserveSpace;
00112 } else if (discStatus == Unknown && !(criteria & PrecisionCritical)) {
00113 recommendation |= ConserveSpace;
00114 } else {
00115 recommendation |= UseAsMuchAsYouLike;
00116 }
00117
00118 } else if (memoryStatus == Marginal) {
00119
00120 if (((criteria & SpeedCritical) ||
00121 (criteria & FrequentLookupLikely)) &&
00122 !(criteria & PrecisionCritical) &&
00123 !(criteria & LongRetentionLikely)) {
00124
00125
00126
00127 if (discStatus != Insufficient) {
00128 recommendation |= PreferMemory;
00129 } else {
00130 recommendation |= UseMemory;
00131 }
00132
00133 recommendation |= ConserveSpace;
00134
00135 } else {
00136
00137 if (discStatus == Insufficient) {
00138 recommendation |= (UseMemory | ConserveSpace);
00139 } else if (discStatus == Marginal) {
00140 recommendation |= (PreferMemory | ConserveSpace);
00141 } else if (discStatus == Unknown) {
00142 recommendation |= (PreferDisc | ConserveSpace);
00143 } else {
00144 recommendation |= (UseDisc | UseAsMuchAsYouLike);
00145 }
00146 }
00147
00148 } else {
00149
00150 if (discStatus == Insufficient) {
00151 recommendation |= (UseMemory | ConserveSpace);
00152 } else if (discStatus != Sufficient) {
00153 recommendation |= (PreferMemory | ConserveSpace);
00154 } else {
00155
00156 if ((criteria & SpeedCritical) ||
00157 (criteria & FrequentLookupLikely)) {
00158 recommendation |= PreferMemory;
00159 if (criteria & PrecisionCritical) {
00160 recommendation |= UseAsMuchAsYouLike;
00161 } else {
00162 recommendation |= ConserveSpace;
00163 }
00164 } else {
00165 recommendation |= PreferDisc;
00166 recommendation |= UseAsMuchAsYouLike;
00167 }
00168 }
00169 }
00170
00171 return Recommendation(recommendation);
00172 }
00173
00174 void
00175 StorageAdviser::notifyPlannedAllocation(AllocationArea area, int size)
00176 {
00177 if (area == MemoryAllocation) m_memoryPlanned += size;
00178 else if (area == DiscAllocation) m_discPlanned += size;
00179
00180
00181 }
00182
00183 void
00184 StorageAdviser::notifyDoneAllocation(AllocationArea area, int size)
00185 {
00186 if (area == MemoryAllocation) {
00187 if (m_memoryPlanned > size) m_memoryPlanned -= size;
00188 else m_memoryPlanned = 0;
00189 } else if (area == DiscAllocation) {
00190 if (m_discPlanned > size) m_discPlanned -= size;
00191 else m_discPlanned = 0;
00192 }
00193
00194
00195 }
00196