Added DirStatCache::GetChildLeafNameHasLock method

This commit is contained in:
Takeshi Nakatani
2025-08-15 11:51:58 +00:00
committed by Andrew Gaul
parent 629207791e
commit 066a2f8fa6
2 changed files with 53 additions and 42 deletions

View File

@ -823,28 +823,22 @@ bool DirStatCache::RemoveChildHasLock(const std::string& strpath)
} }
// make key(leaf name without slash) for children map // make key(leaf name without slash) for children map
std::string child_leaf = strpath.substr(GetPathHasLock().size()); std::string strLeafName;
bool under_child = false; bool hasNestedChildren = false;
std::string::size_type slash_pos = child_leaf.find_first_of('/'); if(!GetChildLeafNameHasLock(strpath, strLeafName, hasNestedChildren)){
return false;
if(slash_pos == (child_leaf.size() - 1)){
// strpath is my sub-directory
child_leaf.resize(slash_pos);
}else if(slash_pos != std::string::npos){
child_leaf.resize(slash_pos);
under_child = true;
} }
// Search in children // Search in children
std::lock_guard<std::mutex> dircachelock(dir_cache_lock); std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
auto iter = children.find(child_leaf); auto iter = children.find(strLeafName);
if(iter == children.cend()){ if(iter == children.cend()){
// not found // not found
return false; return false;
} }
// found // found
if(under_child){ if(hasNestedChildren){
// type must be directory // type must be directory
if(!iter->second->isDirectoryHasLock()){ if(!iter->second->isDirectoryHasLock()){
return false; return false;
@ -919,25 +913,19 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
} }
// make key(leaf name without slash) for children map // make key(leaf name without slash) for children map
std::string child_leaf = strpath.substr(GetPathHasLock().size()); std::string strLeafName;
bool under_child = false; bool hasNestedChildren = false;
std::string::size_type slash_pos = child_leaf.find_first_of('/'); if(!GetChildLeafNameHasLock(strpath, strLeafName, hasNestedChildren)){
return false;
if(slash_pos == (child_leaf.size() - 1)){
// strpath is my sub-directory
child_leaf.resize(slash_pos);
}else if(slash_pos != std::string::npos){
child_leaf.resize(slash_pos);
under_child = true;
} }
// Search in children // Search in children
std::lock_guard<std::mutex> dircachelock(dir_cache_lock); std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
auto iter = children.find(child_leaf); auto iter = children.find(strLeafName);
if(iter != children.end()){ if(iter != children.end()){
if(iter->second->isNegativeHasLock()){ if(iter->second->isNegativeHasLock()){
// found negative type // found negative type
if(under_child){ if(hasNestedChildren){
// strpath is an under child. // strpath is an under child.
// [NOTE] // [NOTE]
@ -959,7 +947,7 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
} }
}else{ }else{
// found not negative type // found not negative type
if(!under_child && IS_NEGATIVE_OBJ(type)){ if(!hasNestedChildren && IS_NEGATIVE_OBJ(type)){
// strpath is a direct child as negative cache // strpath is a direct child as negative cache
children.erase(iter); children.erase(iter);
iter = children.end(); iter = children.end();
@ -969,7 +957,7 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
if(iter != children.end()){ if(iter != children.end()){
// found // found
if(under_child){ if(hasNestedChildren){
// Add an under child // Add an under child
return iter->second->AddHasLock(strpath, pstat, pmeta, type, is_notruncate); return iter->second->AddHasLock(strpath, pstat, pmeta, type, is_notruncate);
}else{ }else{
@ -987,9 +975,9 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
} }
}else{ }else{
// not found, add as a new object // not found, add as a new object
if(under_child){ if(hasNestedChildren){
// First add directory child, and add an under child // First add directory child, and add an under child
std::string subdir = GetPathHasLock() + child_leaf + "/"; // terminate with "/". (if not terminated, it will added automatically.) std::string subdir = GetPathHasLock() + strLeafName + "/"; // terminate with "/". (if not terminated, it will added automatically.)
auto pstatcache = std::make_shared<DirStatCache>(subdir.c_str()); auto pstatcache = std::make_shared<DirStatCache>(subdir.c_str());
if(!pstatcache->AddHasLock(strpath, pstat, pmeta, type, is_notruncate)){ if(!pstatcache->AddHasLock(strpath, pstat, pmeta, type, is_notruncate)){
@ -997,7 +985,7 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
} }
// add as a child // add as a child
children[child_leaf] = std::move(pstatcache); children[strLeafName] = std::move(pstatcache);
}else{ }else{
// create and add as a direct child // create and add as a direct child
@ -1059,7 +1047,7 @@ bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pst
} }
// add as a child // add as a child
children[child_leaf] = std::move(pstatcache); children[strLeafName] = std::move(pstatcache);
} }
} }
return true; return true;
@ -1109,30 +1097,24 @@ std::shared_ptr<StatCacheNode> DirStatCache::FindHasLock(const std::string& strp
} }
// make key(leaf name without slash) for children map // make key(leaf name without slash) for children map
std::string child_leaf = strpath.substr(GetPathHasLock().size()); std::string strLeafName;
bool under_child = false; bool hasNestedChildren = false;
std::string::size_type slash_pos = child_leaf.find_first_of('/'); if(!GetChildLeafNameHasLock(strpath, strLeafName, hasNestedChildren)){
return std::shared_ptr<StatCacheNode>();
if(slash_pos == (child_leaf.size() - 1)){
// strpath is my sub-directory
child_leaf.resize(slash_pos);
}else if(slash_pos != std::string::npos){
child_leaf.resize(slash_pos);
under_child = true;
} }
std::shared_ptr<StatCacheNode> pstatcache; std::shared_ptr<StatCacheNode> pstatcache;
bool isRemovePath = false; bool isRemovePath = false;
{ {
std::lock_guard<std::mutex> dircachelock(dir_cache_lock); std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
auto iter = children.find(child_leaf); auto iter = children.find(strLeafName);
if(iter == children.cend()){ if(iter == children.cend()){
// not found in children // not found in children
return std::shared_ptr<StatCacheNode>(); return std::shared_ptr<StatCacheNode>();
} }
// found in children // found in children
if(under_child){ if(hasNestedChildren){
// search in found child // search in found child
bool childTruncate = false; // Not use in this method bool childTruncate = false; // Not use in this method
return iter->second->FindHasLock(strpath, petagval, childTruncate); return iter->second->FindHasLock(strpath, petagval, childTruncate);
@ -1250,6 +1232,33 @@ bool DirStatCache::TruncateCacheHasLock()
return isTruncated; return isTruncated;
} }
bool DirStatCache::GetChildLeafNameHasLock(const std::string& strpath, std::string& strLeafName, bool& hasNestedChildren)
{
if(strpath.size() < GetPathHasLock().size()){
return false;
}
strLeafName = strpath.substr(GetPathHasLock().size());
if(strLeafName.empty()){
return false;
}
std::string::size_type slash_pos = strLeafName.find_first_of('/');
if(slash_pos == (strLeafName.size() - 1)){
// strpath is my sub-directory leaf
strLeafName.resize(slash_pos);
hasNestedChildren = false;
}else if(slash_pos != std::string::npos){
// strpath is at least two levels deep within this directory.
strLeafName.resize(slash_pos);
hasNestedChildren = true;
}else{
// strpath is my child file leaf
hasNestedChildren = false;
}
return true;
}
void DirStatCache::DumpHasLock(const std::string& indent, bool detail, std::ostringstream& oss) void DirStatCache::DumpHasLock(const std::string& indent, bool detail, std::ostringstream& oss)
{ {
std::string child_indent = indent + " "; std::string child_indent = indent + " ";

View File

@ -265,6 +265,8 @@ class DirStatCache : public StatCacheNode
bool TruncateCacheHasLock() override REQUIRES(StatCacheNode::cache_lock); bool TruncateCacheHasLock() override REQUIRES(StatCacheNode::cache_lock);
bool GetChildLeafNameHasLock(const std::string& strpath, std::string& strLeafName, bool& hasNestedChildren) REQUIRES(StatCacheNode::cache_lock);
void DumpHasLock(const std::string& indent, bool detail, std::ostringstream& oss) override REQUIRES(StatCacheNode::cache_lock); void DumpHasLock(const std::string& indent, bool detail, std::ostringstream& oss) override REQUIRES(StatCacheNode::cache_lock);
public: public: