Commit 5bdfaa1f authored by Georgios Bitzes's avatar Georgios Bitzes

NS: Allow filtering out entire trees out of NamespaceExplorer results

parent 825681e8
Pipeline #470853 passed with stages
in 30 minutes 42 seconds
......@@ -30,8 +30,8 @@ EOSNSNAMESPACE_BEGIN
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
SearchNode::SearchNode(qclient::QClient& qcli, ContainerIdentifier d, eos::SearchNode* prnt)
: id(d), qcl(qcli), parent(prnt),
SearchNode::SearchNode(NamespaceExplorer &expl, ContainerIdentifier d, eos::SearchNode* prnt)
: explorer(expl), id(d), qcl(explorer.qcl), parent(prnt),
containerMd(MetadataFetcher::getContainerFromId(qcl, ContainerIdentifier(id)))
{
fileMap = MetadataFetcher::getFilesInContainer(qcl, ContainerIdentifier(id));
......@@ -83,6 +83,11 @@ void SearchNode::stageFileMds()
//------------------------------------------------------------------------------
std::unique_ptr<SearchNode> SearchNode::expand()
{
ExpansionDecider *decider = explorer.options.expansionDecider.get();
if(decider && !decider->shouldExpandContainer(getContainerInfo())) {
return {}; // nope, this node is being filtered out
}
stageChildren();
if (children.empty()) {
......@@ -134,7 +139,7 @@ void SearchNode::stageChildren()
for (auto it = sortedContainerMap.begin(); it != sortedContainerMap.end();
it++) {
children.emplace_back(new SearchNode(qcl, ContainerIdentifier(it->second), this));
children.emplace_back(new SearchNode(explorer, ContainerIdentifier(it->second), this));
}
}
......@@ -177,7 +182,7 @@ NamespaceExplorer::NamespaceExplorer(const std::string& pth,
if (pathParts.empty()) {
// We're running a search on the root node, expand.
dfsPath.emplace_back(new SearchNode(qcl, ContainerIdentifier(1), nullptr));
dfsPath.emplace_back(new SearchNode(*this, ContainerIdentifier(1), nullptr));
}
// TODO: This for loop looks like a useful primitive for MetadataFetcher,
......@@ -221,7 +226,7 @@ NamespaceExplorer::NamespaceExplorer(const std::string& pth,
staticPath.emplace_back(MetadataFetcher::getContainerFromId(qcl, nextId).get());
} else {
// Final node, expand
dfsPath.emplace_back(new SearchNode(qcl, nextId, nullptr));
dfsPath.emplace_back(new SearchNode(*this, nextId, nullptr));
}
}
}
......
......@@ -41,8 +41,18 @@ class QClient;
EOSNSNAMESPACE_BEGIN
class ExpansionDecider {
public:
//----------------------------------------------------------------------------
//! Returns whether to expand the given container, or ignore it.
//! Useful to filter out certain parts of the namespace tree.
//----------------------------------------------------------------------------
virtual bool shouldExpandContainer(const eos::ns::ContainerMdProto &containerMd) = 0;
};
struct ExplorationOptions {
int depthLimit;
std::shared_ptr<ExpansionDecider> expansionDecider;
};
struct NamespaceItem {
......@@ -55,13 +65,15 @@ struct NamespaceItem {
eos::ns::ContainerMdProto containerMd;
};
class NamespaceExplorer;
//------------------------------------------------------------------------------
//! Represents a node in the search tree.
//------------------------------------------------------------------------------
class SearchNode
{
public:
SearchNode(qclient::QClient& qcl, ContainerIdentifier id, SearchNode* prnt);
SearchNode(NamespaceExplorer &explorer, ContainerIdentifier id, SearchNode* prnt);
inline ContainerIdentifier getID() const
{
return id;
......@@ -97,6 +109,7 @@ public:
eos::ns::ContainerMdProto& getContainerInfo();
private:
NamespaceExplorer &explorer;
ContainerIdentifier id;
qclient::QClient& qcl;
SearchNode* parent = nullptr;
......@@ -143,6 +156,7 @@ public:
bool fetch(NamespaceItem& result);
private:
friend class SearchNode;
std::string buildStaticPath();
std::string buildDfsPath();
......
......@@ -390,6 +390,70 @@ TEST_F(NamespaceExplorerF, BasicSanity) {
ASSERT_FALSE(explorer2.fetch(item));
}
class ContainerFilter : public eos::ExpansionDecider {
public:
virtual bool shouldExpandContainer(const eos::ns::ContainerMdProto &proto) override {
if(proto.name() == "d4") {
std::cerr << "INFO: Filtering out encountered container with name d4." << std::endl;
return false;
}
return true;
}
};
TEST_F(NamespaceExplorerF, ExpansionDecider) {
populateDummyData1();
ExplorationOptions options;
options.depthLimit = 999;
options.expansionDecider.reset(new ContainerFilter());
NamespaceExplorer explorer("/eos/d2", options, qcl());
NamespaceItem item;
ASSERT_TRUE(explorer.fetch(item));
ASSERT_FALSE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/");
for(size_t i = 1; i <= 3; i++) {
ASSERT_TRUE(explorer.fetch(item));
ASSERT_TRUE(item.isFile);
ASSERT_EQ(item.fullPath, SSTR("/eos/d2/asdf" << i));
}
ASSERT_TRUE(explorer.fetch(item));
ASSERT_TRUE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/b");
for(size_t i = 1; i <= 6; i++) {
ASSERT_TRUE(explorer.fetch(item));
ASSERT_TRUE(item.isFile);
ASSERT_EQ(item.fullPath, SSTR("/eos/d2/zzzzz" << i));
}
ASSERT_TRUE(explorer.fetch(item));
ASSERT_FALSE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/d3-1/");
ASSERT_TRUE(explorer.fetch(item));
ASSERT_FALSE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/d3-2/");
ASSERT_TRUE(explorer.fetch(item));
ASSERT_TRUE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/d3-2/my-file");
ASSERT_TRUE(explorer.fetch(item));
ASSERT_FALSE(item.isFile);
ASSERT_EQ(item.fullPath, "/eos/d2/d4/");
ASSERT_FALSE(explorer.fetch(item));
ASSERT_FALSE(explorer.fetch(item));
ASSERT_FALSE(explorer.fetch(item));
}
TEST(OctalParsing, BasicSanity) {
mode_t mode;
ASSERT_TRUE(PermissionHandler::parseOctalMask("0700", mode));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment