Skip to content

Commit f5ce45f

Browse files
committed
filesystem.cc: deduplicate with UniqueID
1 parent 6d96d9d commit f5ce45f

1 file changed

Lines changed: 39 additions & 14 deletions

File tree

src/filesystem.cc

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,55 @@ using namespace llvm;
33

44
#include "utils.h"
55

6+
#include <set>
67
#include <vector>
78

89
void GetFilesInFolder(std::string folder,
910
bool recursive,
1011
bool dir_prefix,
1112
const std::function<void(const std::string&)>& handler) {
1213
EnsureEndsInSlash(folder);
13-
std::vector<std::string> st{folder};
14-
while (st.size()) {
15-
std::error_code ec;
16-
folder = st.back();
17-
st.pop_back();
18-
for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec;
19-
I.increment(ec)) {
20-
auto Status = I->status();
21-
if (!Status) continue;
22-
std::string path = I->path(), filename = sys::path::filename(path);
23-
if (filename[0] != '.' || filename == ".ccls") {
24-
if (sys::fs::is_regular_file(*Status)) {
14+
sys::fs::file_status Status;
15+
if (sys::fs::status(folder, Status, true))
16+
return;
17+
sys::fs::UniqueID ID;
18+
std::vector<std::string> curr{folder};
19+
std::vector<std::pair<std::string, sys::fs::file_status>> succ;
20+
std::set<sys::fs::UniqueID> seen{Status.getUniqueID()};
21+
while (curr.size() || succ.size()) {
22+
if (curr.empty()) {
23+
for (auto& it : succ)
24+
if (!seen.count(it.second.getUniqueID()))
25+
curr.push_back(std::move(it.first));
26+
succ.clear();
27+
} else {
28+
std::error_code ec;
29+
std::string folder1 = curr.back();
30+
curr.pop_back();
31+
for (sys::fs::directory_iterator I(folder1, ec, false), E; I != E && !ec;
32+
I.increment(ec)) {
33+
std::string path = I->path(), filename = sys::path::filename(path);
34+
if ((filename[0] == '.' && filename != ".ccls") ||
35+
sys::fs::status(path, Status, false))
36+
continue;
37+
if (sys::fs::is_symlink_file(Status)) {
38+
if (sys::fs::status(path, Status, true))
39+
continue;
40+
if (sys::fs::is_directory(Status)) {
41+
if (recursive)
42+
succ.emplace_back(path, Status);
43+
continue;
44+
}
45+
}
46+
if (sys::fs::is_regular_file(Status)) {
2547
if (!dir_prefix)
2648
path = path.substr(folder.size());
2749
handler(path);
28-
} else if (recursive && sys::fs::is_directory(*Status))
29-
st.push_back(path);
50+
} else if (recursive && sys::fs::is_directory(Status) &&
51+
!seen.count(ID = Status.getUniqueID())) {
52+
curr.push_back(path);
53+
seen.insert(ID);
54+
}
3055
}
3156
}
3257
}

0 commit comments

Comments
 (0)