1
0

AnvilStats: complete per-biome blocktype statistics

git-svn-id: http://mc-server.googlecode.com/svn/trunk@897 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com
2012-09-28 20:17:29 +00:00
parent 19a3981eb9
commit 3165458c59
9 changed files with 431 additions and 32 deletions

View File

@@ -8,6 +8,7 @@
#include "Callback.h"
#include "../source/WorldStorage/FastNBT.h"
#include "zlib.h"
#include "Utils.h"
@@ -36,16 +37,22 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces
void cProcessor::cThread::Execute(void)
{
LOG("Started a new thread: %d", cIsThread::GetCurrentID());
m_ParentProcessor.m_ThreadsHaveStarted.Set();
for (;;)
{
AString FileName = m_ParentProcessor.GetOneFileName();
if (FileName.empty())
{
// All done, terminate the thread
return;
break;
}
ProcessFile(FileName);
} // for-ever
LOG("Thread %d terminated", cIsThread::GetCurrentID());
}
@@ -264,6 +271,8 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
return false;
}
bool SectionProcessed[16];
memset(SectionProcessed, 0, sizeof(SectionProcessed));
for (int Tag = a_NBT.GetFirstChild(Sections); Tag > 0; Tag = a_NBT.GetNextSibling(Tag))
{
int YTag = a_NBT.FindChildByName(Tag, "Y");
@@ -278,8 +287,14 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
continue;
}
unsigned char SectionY = a_NBT.GetByte(YTag);
if (SectionY >= 16)
{
LOG("WARNING: Section Y >= 16 (%d), high world, wtf? Skipping section!", SectionY);
continue;
}
if (m_Callback.OnSection(
a_NBT.GetByte(YTag),
SectionY,
(const BLOCKTYPE *) (a_NBT.GetData(BlocksTag)),
(AddTag > 0) ? (const NIBBLETYPE *)(a_NBT.GetData(AddTag)) : NULL,
(const NIBBLETYPE *)(a_NBT.GetData(DataTag)),
@@ -289,8 +304,18 @@ bool cProcessor::cThread::ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cPars
{
return true;
}
SectionProcessed[SectionY] = true;
} // for Tag - Sections[]
// Call the callback for empty sections:
for (unsigned char y = 0; y < 16; y++)
{
if (!SectionProcessed[y])
{
m_Callback.OnEmptySection(y);
}
}
return false;
}
@@ -322,26 +347,18 @@ void cProcessor::ProcessWorld(const AString & a_WorldFolder, cCallbackFactory &
{
PopulateFileQueue(a_WorldFolder);
// Start as many threads as there are cores:
// Get number of cores by querying the system process affinity mask
DWORD Affinity, ProcAffinity;
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
while (Affinity > 0)
// Start as many threads as there are cores, plus one:
// (One more thread can be in the file-read IO block while all other threads crunch the numbers)
int NumThreads = GetNumCores() + 1;
for (int i = 0; i < NumThreads; i++)
{
if ((Affinity & 1) == 1)
{
cCallback * Callback = a_CallbackFactory.GetNewCallback();
m_Threads.push_back(new cThread(*Callback, *this));
}
Affinity >>= 1;
} // while (Affinity > 0)
if (m_Threads.size() == 0)
{
LOG("Zero cores detected - how am I running? Running in a single thread.");
cCallback * Callback = a_CallbackFactory.GetNewCallback();
m_Threads.push_back(new cThread(*Callback, *this));
}
// Wait for the first thread to start processing:
m_ThreadsHaveStarted.Wait();
// Wait for all threads to finish
// simply by calling each thread's destructor sequentially
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
@@ -359,7 +376,10 @@ void cProcessor::PopulateFileQueue(const AString & a_WorldFolder)
LOG("Processing world in \"%s\"...", a_WorldFolder.c_str());
AString Path = a_WorldFolder;
Path.push_back(cFile::PathSeparator);
if (!Path.empty() && (Path[Path.length() - 1] != cFile::PathSeparator))
{
Path.push_back(cFile::PathSeparator);
}
AStringList AllFiles = GetDirectoryContents(Path.c_str());
for (AStringList::iterator itr = AllFiles.begin(), end = AllFiles.end(); itr != end; ++itr)
{