| 53 | } // namespace |
| 54 | |
| 55 | Status GetMatchingPaths(FileSystem* fs, Env* env, const string& pattern, |
| 56 | std::vector<string>* results) { |
| 57 | results->clear(); |
| 58 | // Find the fixed prefix by looking for the first wildcard. |
| 59 | string fixed_prefix = pattern.substr(0, pattern.find_first_of("*?[\\")); |
| 60 | string eval_pattern = pattern; |
| 61 | std::vector<string> all_files; |
| 62 | string dir(io::Dirname(fixed_prefix)); |
| 63 | // If dir is empty then we need to fix up fixed_prefix and eval_pattern to |
| 64 | // include . as the top level directory. |
| 65 | if (dir.empty()) { |
| 66 | dir = "."; |
| 67 | fixed_prefix = io::JoinPath(dir, fixed_prefix); |
| 68 | eval_pattern = io::JoinPath(dir, pattern); |
| 69 | } |
| 70 | |
| 71 | // Setup a BFS to explore everything under dir. |
| 72 | std::deque<string> dir_q; |
| 73 | dir_q.push_back(dir); |
| 74 | Status ret; // Status to return. |
| 75 | // children_dir_status holds is_dir status for children. It can have three |
| 76 | // possible values: OK for true; FAILED_PRECONDITION for false; CANCELLED |
| 77 | // if we don't calculate IsDirectory (we might do that because there isn't |
| 78 | // any point in exploring that child path). |
| 79 | std::vector<Status> children_dir_status; |
| 80 | while (!dir_q.empty()) { |
| 81 | string current_dir = dir_q.front(); |
| 82 | dir_q.pop_front(); |
| 83 | std::vector<string> children; |
| 84 | Status s = fs->GetChildren(current_dir, &children); |
| 85 | // In case PERMISSION_DENIED is encountered, we bail here. |
| 86 | if (s.code() == tensorflow::error::PERMISSION_DENIED) { |
| 87 | continue; |
| 88 | } |
| 89 | ret.Update(s); |
| 90 | if (children.empty()) continue; |
| 91 | // This IsDirectory call can be expensive for some FS. Parallelizing it. |
| 92 | children_dir_status.resize(children.size()); |
| 93 | ForEach(0, children.size(), |
| 94 | [fs, ¤t_dir, &children, &fixed_prefix, |
| 95 | &children_dir_status](int i) { |
| 96 | const string child_path = io::JoinPath(current_dir, children[i]); |
| 97 | // In case the child_path doesn't start with the fixed_prefix then |
| 98 | // we don't need to explore this path. |
| 99 | if (!absl::StartsWith(child_path, fixed_prefix)) { |
| 100 | children_dir_status[i] = Status(tensorflow::error::CANCELLED, |
| 101 | "Operation not needed"); |
| 102 | } else { |
| 103 | children_dir_status[i] = fs->IsDirectory(child_path); |
| 104 | } |
| 105 | }); |
| 106 | for (int i = 0; i < children.size(); ++i) { |
| 107 | const string child_path = io::JoinPath(current_dir, children[i]); |
| 108 | // If the IsDirectory call was cancelled we bail. |
| 109 | if (children_dir_status[i].code() == tensorflow::error::CANCELLED) { |
| 110 | continue; |
| 111 | } |
| 112 | // If the child is a directory add it to the queue. |
no test coverage detected