Skip to content

Commit

Permalink
Handle recursivity in getDirectorySize.
Browse files Browse the repository at this point in the history
  • Loading branch information
herve-er committed May 6, 2024
1 parent da36fef commit bc177d1
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 10 deletions.
16 changes: 15 additions & 1 deletion src/libcommonserver/io/iohelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ bool IoHelper::getFileSize(const SyncPath &path, uint64_t &size, IoError &ioErro
return true;
}

bool IoHelper::getDirectorySize(const SyncPath &path, uint64_t &size, IoError &ioError) {
bool IoHelper::getDirectorySize(const SyncPath &path, uint64_t &size, unsigned int maxDepth, bool &skipedTooDeep,
IoError &ioError) {
ItemType itemType;
const bool success = getItemType(path, itemType);
ioError = itemType.ioError;
Expand All @@ -350,6 +351,19 @@ bool IoHelper::getDirectorySize(const SyncPath &path, uint64_t &size, IoError &i
bool endOfDirectory = false;
size = 0;
while (dir.next(entry, endOfDirectory, ioError) && !endOfDirectory) {
if (entry.is_directory()) {
if (maxDepth == 0) {
LOG_WARN(Log::instance()->getLogger(), "Max depth reached in getDirectorySize, skipping deeper directories: "
<< Utility::formatSyncPath(path).c_str());
skipedTooDeep = true;
continue;
}
uint64_t entrySize;
if (!getDirectorySize(entry.path(), entrySize, maxDepth - 1, skipedTooDeep, ioError)) {
return false;
}
size += entrySize;
}
uint64_t entrySize;
std::error_code ec;
entrySize = _fileSize(entry.path(), ec);
Expand Down
9 changes: 6 additions & 3 deletions src/libcommonserver/io/iohelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct IoHelper {
#ifdef _WIN32
static int _getAndSetRightsMethod;
#endif

static IoError stdError2ioError(int error) noexcept;
static IoError stdError2ioError(const std::error_code &ec) noexcept;
static IoError posixError2ioError(int error) noexcept;
Expand Down Expand Up @@ -184,15 +184,18 @@ struct IoHelper {
static bool getFileSize(const SyncPath &path, uint64_t &size, IoError &ioError);

//! Get the size of the directory indicated by `path`, in bytes.
//! This funciton is recursive.
//! This funciton is recursiv.
/*!
\param path is the file system path of a directory.
\param size holds the size in bytes of the directory indicated by path in case of success.
\param ioError holds the error associated to a failure of the underlying OS API call, if any.
\param maxDepth is the maximum depth of the recursion.
\param skipedTooDeep is set to true if the recursion skipped some directories because the depth was too high.
\return true if no unexpected error occurred, false otherwise. If path indicates a File,
the function returns false and ioError is set with IoErrorIsADirectory.
*/
static bool getDirectorySize(const SyncPath &path, uint64_t &size, IoError &ioError);
static bool getDirectorySize(const SyncPath &path, uint64_t &size, unsigned int maxDepth, bool &skipedTooDeep,
IoError &ioError);

//! Check if the file indicated by `path` is accessible.
//! This is especially useful on Windows where the OS will send a CREATE event while the file is still being copied.
Expand Down
4 changes: 2 additions & 2 deletions src/libcommonserver/log/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ Log::Log(const log4cplus::tstring &filePath) : _filePath(filePath) {
bool Log::getLogEstimatedSize(uint64_t &size, IoError &ioError) {
const SyncPath logPath = _filePath.parent_path();
ioError = IoErrorSuccess;

for (int i = 0; i < 2; i++) { // Retry once in case a log file is archived/created during the first iteration
bool result = IoHelper::getDirectorySize(logPath, size, ioError);
bool tooDeep = false;
bool result = IoHelper::getDirectorySize(logPath, size, 0, tooDeep, ioError);
if (result && ioError == IoErrorSuccess) {
return true;
}
Expand Down
12 changes: 8 additions & 4 deletions test/libcommonserver/log/testlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ void TestLog::testCopyLogsTo(void) {
CPPUNIT_ASSERT_EQUAL(ExitCodeOk, exitCode);

uint64_t tempDirSize = 0;
IoHelper::getDirectorySize(tempDir.path, tempDirSize, err);
bool tooDeep = false;
IoHelper::getDirectorySize(tempDir.path, tempDirSize, 0, tooDeep, err);
CPPUNIT_ASSERT_EQUAL(IoErrorSuccess, err);
CPPUNIT_ASSERT_EQUAL(logDirsize, tempDirSize);
}
Expand Down Expand Up @@ -157,7 +158,8 @@ void TestLog::testCopyParmsDbTo(void) {
CPPUNIT_ASSERT_EQUAL(ExitCodeOk, exitCode);

uint64_t tempDirSize = 0;
IoHelper::getDirectorySize(tempDir.path, tempDirSize, err);
bool tooDeep = false;
IoHelper::getDirectorySize(tempDir.path, tempDirSize, 0, tooDeep, err);
CPPUNIT_ASSERT_EQUAL(IoErrorSuccess, err);
CPPUNIT_ASSERT_EQUAL(parmsDbSize, tempDirSize);
}
Expand All @@ -183,7 +185,9 @@ void TestLog::testCompressLogs(void) {
CPPUNIT_ASSERT_EQUAL(IoErrorSuccess, err);

uint64_t logDirSize = 0;
CPPUNIT_ASSERT_EQUAL(true, IoHelper::getDirectorySize(logDir, logDirSize, err));
bool tooDeep = false;

CPPUNIT_ASSERT_EQUAL(true, IoHelper::getDirectorySize(logDir, logDirSize, 0, tooDeep, err));
CPPUNIT_ASSERT_EQUAL(IoErrorSuccess, err);
CPPUNIT_ASSERT(logDirSize >= 0);

Expand All @@ -194,7 +198,7 @@ void TestLog::testCompressLogs(void) {
CPPUNIT_ASSERT_EQUAL(ExitCodeOk, exitCode);

uint64_t tempDirSize = 0;
IoHelper::getDirectorySize(tempDir.path, tempDirSize, err);
IoHelper::getDirectorySize(tempDir.path, tempDirSize, 0, tooDeep, err);
CPPUNIT_ASSERT_EQUAL(IoErrorSuccess, err);
CPPUNIT_ASSERT(tempDirSize < logDirSize);

Expand Down

0 comments on commit bc177d1

Please sign in to comment.