| 197 | } |
| 198 | |
| 199 | Result<FileInfoVector> GlobFiles(const std::shared_ptr<FileSystem>& filesystem, |
| 200 | const std::string& glob) { |
| 201 | // TODO: ARROW-17640 |
| 202 | // The candidate entries at the current depth level. |
| 203 | // We start with the filesystem root. |
| 204 | FileInfoVector results{FileInfo("", FileType::Directory)}; |
| 205 | // The exact tail that will later require matching with candidate entries |
| 206 | std::string current_tail; |
| 207 | auto is_leading_slash = HasLeadingSlash(glob); |
| 208 | auto split_glob = SplitAbstractPath(glob, '/'); |
| 209 | |
| 210 | // Process one depth level at once, from root to leaf |
| 211 | for (const auto& glob_component : split_glob) { |
| 212 | if (glob_component.find_first_of("*?") == std::string::npos) { |
| 213 | // If there are no wildcards at the current level, just append |
| 214 | // the exact glob path component. |
| 215 | current_tail = ConcatAbstractPath(current_tail, glob_component); |
| 216 | continue; |
| 217 | } else { |
| 218 | FileInfoVector children; |
| 219 | for (const auto& res : results) { |
| 220 | if (res.type() != FileType::Directory) { |
| 221 | continue; |
| 222 | } |
| 223 | FileSelector selector; |
| 224 | selector.base_dir = current_tail.empty() |
| 225 | ? res.path() |
| 226 | : ConcatAbstractPath(res.path(), current_tail); |
| 227 | if (is_leading_slash) { |
| 228 | selector.base_dir = EnsureLeadingSlash(selector.base_dir); |
| 229 | } |
| 230 | ARROW_ASSIGN_OR_RAISE(auto entries, filesystem->GetFileInfo(selector)); |
| 231 | Globber globber(ConcatAbstractPath(selector.base_dir, glob_component)); |
| 232 | for (auto&& entry : entries) { |
| 233 | if (globber.Matches(entry.path())) { |
| 234 | children.push_back(std::move(entry)); |
| 235 | } |
| 236 | } |
| 237 | } |
| 238 | results = std::move(children); |
| 239 | current_tail.clear(); |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | if (!current_tail.empty()) { |
| 244 | std::vector<std::string> paths; |
| 245 | paths.reserve(results.size()); |
| 246 | for (const auto& file : results) { |
| 247 | paths.push_back(ConcatAbstractPath(file.path(), current_tail)); |
| 248 | } |
| 249 | ARROW_ASSIGN_OR_RAISE(results, filesystem->GetFileInfo(paths)); |
| 250 | } |
| 251 | |
| 252 | std::vector<FileInfo> out; |
| 253 | for (auto&& file : results) { |
| 254 | if (file.type() != FileType::NotFound) { |
| 255 | out.push_back(std::move(file)); |
| 256 | } |