1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-21 14:50:06 +02:00

Gather balance info hashes into one struct guarded by an accessor...

Doing BalanceInfoDel in this delayed fashion will be needed when the other
call to it is eliminated, as shared_ptr simplifies the management of BlockFile
and makes the many calls to Ref and Deref disappear.
This commit is contained in:
Paul Licameli 2016-08-15 13:49:59 -04:00
parent cde61edbf4
commit 84ccdca5c3
4 changed files with 79 additions and 6 deletions

View File

@ -109,10 +109,15 @@ BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
mSilentLog=FALSE; mSilentLog=FALSE;
} }
// static
unsigned long BlockFile::gBlockFileDestructionCount { 0 };
BlockFile::~BlockFile() BlockFile::~BlockFile()
{ {
if (!IsLocked() && mFileName.HasName()) if (!IsLocked() && mFileName.HasName())
wxRemoveFile(mFileName.GetFullPath()); wxRemoveFile(mFileName.GetFullPath());
++gBlockFileDestructionCount;
} }
/// Returns the file name of the disk file associated with this /// Returns the file name of the disk file associated with this

View File

@ -64,6 +64,8 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
BlockFile(wxFileNameWrapper &&fileName, sampleCount samples); BlockFile(wxFileNameWrapper &&fileName, sampleCount samples);
virtual ~BlockFile(); virtual ~BlockFile();
static unsigned long gBlockFileDestructionCount;
// Reading // Reading
/// Retrieves audio data from this BlockFile /// Retrieves audio data from this BlockFile

View File

@ -319,6 +319,8 @@ DirManager::DirManager()
{ {
wxLogDebug(wxT("DirManager: Created new instance.")); wxLogDebug(wxT("DirManager: Created new instance."));
mLastBlockFileDestructionCount = BlockFile::gBlockFileDestructionCount;
// Seed the random number generator. // Seed the random number generator.
// this need not be strictly uniform or random, but it should give // this need not be strictly uniform or random, but it should give
// unclustered numbers // unclustered numbers
@ -347,8 +349,11 @@ DirManager::DirManager()
// toplevel pool hash is fully populated to begin // toplevel pool hash is fully populated to begin
{ {
int i; // We can bypass the accessor function while initializing
for(i=0; i< 256; i++) dirTopPool[i]=0; auto &balanceInfo = mBalanceInfo;
auto &dirTopPool = balanceInfo.dirTopPool;
for(int i = 0; i < 256; ++i)
dirTopPool[i] = 0;
} }
// Make sure there is plenty of space for temp files // Make sure there is plenty of space for temp files
@ -650,6 +655,12 @@ int DirManager::BalanceMidAdd(int topnum, int midkey)
{ {
// enter the midlevel directory if it doesn't exist // enter the midlevel directory if it doesn't exist
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
if(dirMidPool.find(midkey) == dirMidPool.end() && if(dirMidPool.find(midkey) == dirMidPool.end() &&
dirMidFull.find(midkey) == dirMidFull.end()){ dirMidFull.find(midkey) == dirMidFull.end()){
dirMidPool[midkey]=0; dirMidPool[midkey]=0;
@ -668,6 +679,10 @@ int DirManager::BalanceMidAdd(int topnum, int midkey)
void DirManager::BalanceFileAdd(int midkey) void DirManager::BalanceFileAdd(int midkey)
{ {
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
// increment the midlevel directory usage information // increment the midlevel directory usage information
if(dirMidPool.find(midkey) != dirMidPool.end()){ if(dirMidPool.find(midkey) != dirMidPool.end()){
dirMidPool[midkey]++; dirMidPool[midkey]++;
@ -700,11 +715,46 @@ void DirManager::BalanceInfoAdd(const wxString &file)
} }
} }
auto DirManager::GetBalanceInfo() -> BalanceInfo &
{
// Before returning the map,
// see whether any block files have disappeared,
// and if so update
auto count = BlockFile::gBlockFileDestructionCount;
if ( mLastBlockFileDestructionCount != count ) {
auto it = mBlockFileHash.begin(), end = mBlockFileHash.end();
while (it != end)
{
BlockFilePtr ptr { it->second };
if (!ptr) {
auto name = it->first;
mBlockFileHash.erase( it++ );
BalanceInfoDel( name );
}
else
++it;
}
}
mLastBlockFileDestructionCount = count;
return mBalanceInfo;
}
// Note that this will try to clean up directories out from under even // Note that this will try to clean up directories out from under even
// locked blockfiles; this is actually harmless as the rmdir will fail // locked blockfiles; this is actually harmless as the rmdir will fail
// on non-empty directories. // on non-empty directories.
void DirManager::BalanceInfoDel(const wxString &file) void DirManager::BalanceInfoDel(const wxString &file)
{ {
// do not use GetBalanceInfo(),
// rather this function will be called from there.
auto &balanceInfo = mBalanceInfo;
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
const wxChar *s=file.c_str(); const wxChar *s=file.c_str();
if(s[0]==wxT('e')){ if(s[0]==wxT('e')){
// this is one of the modern two-deep managed files // this is one of the modern two-deep managed files
@ -766,6 +816,11 @@ void DirManager::BalanceInfoDel(const wxString &file)
// perform maintainence // perform maintainence
wxFileNameWrapper DirManager::MakeBlockFileName() wxFileNameWrapper DirManager::MakeBlockFileName()
{ {
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
wxFileNameWrapper ret; wxFileNameWrapper ret;
wxString baseFileName; wxString baseFileName;

View File

@ -179,10 +179,19 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
bool MoveOrCopyToNewProjectDirectory(BlockFile *f, bool copy); bool MoveOrCopyToNewProjectDirectory(BlockFile *f, bool copy);
BlockHash mBlockFileHash; // repository for blockfiles BlockHash mBlockFileHash; // repository for blockfiles
// Hashes for management of the sub-directory tree of _data
struct BalanceInfo
{
DirHash dirTopPool; // available toplevel dirs DirHash dirTopPool; // available toplevel dirs
DirHash dirTopFull; // full toplevel dirs DirHash dirTopFull; // full toplevel dirs
DirHash dirMidPool; // available two-level dirs DirHash dirMidPool; // available two-level dirs
DirHash dirMidFull; // full two-level dirs DirHash dirMidFull; // full two-level dirs
} mBalanceInfo;
// Accessor for the balance info, may need to do a delayed update for
// deletion in case other threads delete block files
BalanceInfo &GetBalanceInfo();
void BalanceInfoDel(const wxString&); void BalanceInfoDel(const wxString&);
void BalanceInfoAdd(const wxString&); void BalanceInfoAdd(const wxString&);
@ -204,6 +213,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
sampleCount mMaxSamples; // max samples per block sampleCount mMaxSamples; // max samples per block
unsigned long mLastBlockFileDestructionCount { 0 };
static wxString globaltemp; static wxString globaltemp;
wxString mytemp; wxString mytemp;
static int numDirManagers; static int numDirManagers;