Mercurial > hg > easaier-soundaccess
diff base/StorageAdviser.cpp @ 0:fc9323a41f5a
start base : Sonic Visualiser sv1-1.0rc1
author | lbajardsilogic |
---|---|
date | Fri, 11 May 2007 09:08:14 +0000 |
parents | |
children | be6f263fa0ab |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/StorageAdviser.cpp Fri May 11 09:08:14 2007 +0000 @@ -0,0 +1,187 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "StorageAdviser.h" + +#include "Exceptions.h" +#include "TempDirectory.h" + +#include "system/System.h" + +#include <iostream> + +long StorageAdviser::m_discPlanned = 0; +long StorageAdviser::m_memoryPlanned = 0; + +StorageAdviser::Recommendation +StorageAdviser::recommend(Criteria criteria, + int minimumSize, + int maximumSize) +{ + std::cerr << "StorageAdviser::recommend: Criteria " << criteria + << ", minimumSize " << minimumSize + << ", maximumSize " << maximumSize << std::endl; + + QString path = TempDirectory::getInstance()->getPath(); + int discFree = GetDiscSpaceMBAvailable(path.toLocal8Bit()); + int memoryFree, memoryTotal; + GetRealMemoryMBAvailable(memoryFree, memoryTotal); + + if (discFree > m_discPlanned / 1024 + 1) { + discFree -= m_discPlanned / 1024 + 1; + } else if (discFree > 0) { // can also be -1 for unknown + discFree = 0; + } + + if (memoryFree > m_memoryPlanned / 1024 + 1) { + memoryFree -= m_memoryPlanned / 1024 + 1; + } else if (memoryFree > 0) { // can also be -1 for unknown + memoryFree = 0; + } + + std::cerr << "Disc space: " << discFree << ", memory free: " << memoryFree << ", memory total: " << memoryTotal << std::endl; + + //!!! We have a potentially serious problem here if multiple + //recommendations are made in advance of any of the resulting + //allocations, as the allocations that have been recommended for + //won't be taken into account in subsequent recommendations. + + enum StorageStatus { + Unknown, + Insufficient, + Marginal, + Sufficient + }; + + StorageStatus memoryStatus = Unknown; + StorageStatus discStatus = Unknown; + + int minmb = minimumSize / 1024 + 1; + int maxmb = maximumSize / 1024 + 1; + + if (memoryFree == -1) memoryStatus = Unknown; + else if (minmb > (memoryFree * 3) / 4) memoryStatus = Insufficient; + else if (maxmb > (memoryFree * 3) / 4) memoryStatus = Marginal; + else if (minmb > (memoryFree / 3)) memoryStatus = Marginal; + else if (memoryTotal == -1 || + minmb > (memoryTotal / 10)) memoryStatus = Marginal; + else memoryStatus = Sufficient; + + if (discFree == -1) discStatus = Unknown; + else if (minmb > (discFree * 3) / 4) discStatus = Insufficient; + else if (maxmb > (discFree / 4)) discStatus = Marginal; + else if (minmb > (discFree / 10)) discStatus = Marginal; + else discStatus = Sufficient; + + std::cerr << "Memory status: " << memoryStatus << ", disc status " + << discStatus << std::endl; + + int recommendation = NoRecommendation; + + if (memoryStatus == Insufficient || memoryStatus == Unknown) { + + recommendation |= UseDisc; + + if (discStatus == Insufficient && minmb > discFree) { + throw InsufficientDiscSpace(path, minmb, discFree); + } + + if (discStatus == Insufficient || discStatus == Marginal) { + recommendation |= ConserveSpace; + } else if (discStatus == Unknown && !(criteria & PrecisionCritical)) { + recommendation |= ConserveSpace; + } else { + recommendation |= UseAsMuchAsYouLike; + } + + } else if (memoryStatus == Marginal) { + + if (((criteria & SpeedCritical) || + (criteria & FrequentLookupLikely)) && + !(criteria & PrecisionCritical) && + !(criteria & LongRetentionLikely)) { + + // requirements suggest a preference for memory + + if (discStatus != Insufficient) { + recommendation |= PreferMemory; + } else { + recommendation |= UseMemory; + } + + recommendation |= ConserveSpace; + + } else { + + if (discStatus == Insufficient) { + recommendation |= (UseMemory | ConserveSpace); + } else if (discStatus == Marginal) { + recommendation |= (PreferMemory | ConserveSpace); + } else if (discStatus == Unknown) { + recommendation |= (PreferDisc | ConserveSpace); + } else { + recommendation |= (UseDisc | UseAsMuchAsYouLike); + } + } + + } else { + + if (discStatus == Insufficient) { + recommendation |= (UseMemory | ConserveSpace); + } else if (discStatus != Sufficient) { + recommendation |= (PreferMemory | ConserveSpace); + } else { + + if ((criteria & SpeedCritical) || + (criteria & FrequentLookupLikely)) { + recommendation |= PreferMemory; + if (criteria & PrecisionCritical) { + recommendation |= UseAsMuchAsYouLike; + } else { + recommendation |= ConserveSpace; + } + } else { + recommendation |= PreferDisc; + recommendation |= UseAsMuchAsYouLike; + } + } + } + + return Recommendation(recommendation); +} + +void +StorageAdviser::notifyPlannedAllocation(AllocationArea area, int size) +{ + if (area == MemoryAllocation) m_memoryPlanned += size; + else if (area == DiscAllocation) m_discPlanned += size; +// std::cerr << "storage planned up: memory: " << m_memoryPlanned << ", disc " +// << m_discPlanned << std::endl; +} + +void +StorageAdviser::notifyDoneAllocation(AllocationArea area, int size) +{ + if (area == MemoryAllocation) { + if (m_memoryPlanned > size) m_memoryPlanned -= size; + else m_memoryPlanned = 0; + } else if (area == DiscAllocation) { + if (m_discPlanned > size) m_discPlanned -= size; + else m_discPlanned = 0; + } +// std::cerr << "storage planned down: memory: " << m_memoryPlanned << ", disc " +// << m_discPlanned << std::endl; +} +