* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef OMNISTREAM_DIRECTORYSTATEHANDLE_H
#define OMNISTREAM_DIRECTORYSTATEHANDLE_H
#include "StateObject.h"
#include "core/fs/Path.h"
#include <string>
#include <filesystem>
class DirectoryStateHandle : public StateObject {
public:
DirectoryStateHandle(const Path& directory, long directorySize)
: directoryString_(directory.toString()),
directorySize_(directorySize),
directory_(directory) {}
DirectoryStateHandle(const nlohmann::json& json)
: directoryString_(json.contains("directoryString") ? json["directoryString"].get<std::string>()
: throw std::invalid_argument("DirectoryStateHandle 'directoryString' field missing")),
directorySize_(json.contains("stateSize") ? json["stateSize"].get<long>()
: throw std::invalid_argument("DirectoryStateHandle 'directorySize' field missing")),
directory_(Path(directoryString_)) {}
static DirectoryStateHandle forPathWithSize(const Path& directory)
{
long size = 0;
try {
size = computeDirectorySize(directory.toString());
} catch (...) {
}
return DirectoryStateHandle(directory, size);
}
static std::unique_ptr<DirectoryStateHandle> forPathWithSizePtr(const Path& directory)
{
long size = 0;
try {
size = computeDirectorySize(directory.toString());
} catch (...) {
}
return std::make_unique<DirectoryStateHandle>(directory, size);
}
void DiscardState() override
{
std::error_code ec;
std::filesystem::remove_all(directoryString_, ec);
if (ec) {
throw std::runtime_error("Failed to delete directory " + directoryString_ + ": " + ec.message());
}
}
long GetStateSize() const override
{
return directorySize_;
}
const Path& getDirectory()
{
return directory_;
}
bool operator==(const DirectoryStateHandle& other) const
{
return directoryString_ == other.directoryString_;
}
std::string ToString() const override
{
nlohmann::json json;
json["stateHandleName"] = "DirectoryStateHandle";
json["directory"] = directoryString_;
json["stateSize"] = directorySize_;
return json.dump();
}
private:
static long computeDirectorySize(const std::filesystem::path& dir)
{
std::error_code ec;
uintmax_t total = 0;
for (auto it = std::filesystem::recursive_directory_iterator(dir, ec);
it != std::filesystem::recursive_directory_iterator();
it.increment(ec)) {
if (ec) {
continue;
}
if (std::filesystem::is_regular_file(it->path(), ec) && !ec) {
total += std::filesystem::file_size(it->path(), ec);
}
}
return static_cast<long>(total);
}
std::string directoryString_;
long directorySize_;
Path directory_;
};
#endif