68 lines
2.3 KiB
C++
68 lines
2.3 KiB
C++
#include "traversal.h"
|
|
|
|
#include <blobstore/implementations/onblocks/datanodestore/DataInnerNode.h>
|
|
|
|
using blockstore::BlockId;
|
|
using blockstore::BlockStore;
|
|
using cryfs::fsblobstore::FsBlobStore;
|
|
using cryfs::fsblobstore::DirBlob;
|
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
|
using cpputils::dynamic_pointer_move;
|
|
|
|
using std::vector;
|
|
using std::function;
|
|
using boost::none;
|
|
|
|
namespace cryfs_stats {
|
|
|
|
void forEachBlock(BlockStore* blockStore, const vector<function<void (const BlockId& blobId)>>& callbacks) {
|
|
blockStore->forEachBlock([&callbacks] (const BlockId& blockId) {
|
|
for(const auto& callback : callbacks) {
|
|
callback(blockId);
|
|
}
|
|
});
|
|
}
|
|
|
|
// NOLINTNEXTLINE(misc-no-recursion)
|
|
void forEachReachableBlob(FsBlobStore* blobStore, const BlockId& rootId, const vector<function<void (const BlockId& blobId)>>& callbacks) {
|
|
for (const auto& callback : callbacks) {
|
|
callback(rootId);
|
|
}
|
|
|
|
auto rootBlob = blobStore->load(rootId);
|
|
ASSERT(rootBlob != none, "Blob not found but referenced from directory entry");
|
|
|
|
auto rootDir = dynamic_pointer_move<DirBlob>(*rootBlob);
|
|
if (rootDir != none) {
|
|
vector<fspp::Dir::Entry> children;
|
|
children.reserve((*rootDir)->NumChildren());
|
|
(*rootDir)->AppendChildrenTo(&children);
|
|
|
|
for (const auto& child : children) {
|
|
auto childEntry = (*rootDir)->GetChild(child.name);
|
|
ASSERT(childEntry != none, "We just got this from the entry list, it must exist.");
|
|
auto childId = childEntry->blockId();
|
|
forEachReachableBlob(blobStore, childId, callbacks);
|
|
}
|
|
}
|
|
}
|
|
|
|
// NOLINTNEXTLINE(misc-no-recursion)
|
|
void forEachReachableBlockInBlob(DataNodeStore* nodeStore, const BlockId& rootId, const vector<function<void (const BlockId& blockId)>>& callbacks) {
|
|
for (const auto& callback : callbacks) {
|
|
callback(rootId);
|
|
}
|
|
|
|
auto node = nodeStore->load(rootId);
|
|
auto innerNode = dynamic_pointer_move<DataInnerNode>(*node);
|
|
if (innerNode != none) {
|
|
for (uint32_t childIndex = 0; childIndex < (*innerNode)->numChildren(); ++childIndex) {
|
|
auto childId = (*innerNode)->readChild(childIndex).blockId();
|
|
forEachReachableBlockInBlob(nodeStore, childId, callbacks);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|