|
18 | 18 | import contextlib |
19 | 19 | import dataclasses |
20 | 20 | import functools |
| 21 | +import glob |
21 | 22 | import inspect |
22 | 23 | import os |
23 | 24 | import re |
| 25 | +import threading |
24 | 26 | import types |
25 | 27 | from typing import Any, Callable, Dict, Iterable, Mapping, Optional, Sequence, Tuple, Type, Union |
26 | 28 |
|
@@ -1597,3 +1599,45 @@ def function_name(function) -> str: |
1597 | 1599 | return "" |
1598 | 1600 |
|
1599 | 1601 |
|
| 1602 | +# Lock to prevent multiple threads from calling tf.io.gfile.glob on the same |
| 1603 | +# file pattern at the same time. |
| 1604 | +_LIST_SHARD_LOCKS: dict[str, threading.Lock] = collections.defaultdict( |
| 1605 | + threading.Lock |
| 1606 | +) |
| 1607 | + |
| 1608 | + |
| 1609 | +def list_files(file_patterns: Union[str, Iterable[str]]) -> list[str]: |
| 1610 | + """Returns a sorted list of file for the given file pattern. |
| 1611 | +
|
| 1612 | + Note that shard patterns like `foo@2` are not expanded. Only glob patterns |
| 1613 | + are expanded, e.g., `foo*`. |
| 1614 | +
|
| 1615 | + Args: |
| 1616 | + file_patterns: A string or an iterable of strings, each of which is a file |
| 1617 | + pattern to expand. |
| 1618 | + """ |
| 1619 | + if isinstance(file_patterns, str): |
| 1620 | + file_patterns = [file_patterns] |
| 1621 | + |
| 1622 | + result = [] |
| 1623 | + for file_pattern in file_patterns: |
| 1624 | + if not glob.has_magic(file_pattern): |
| 1625 | + result.append(file_pattern) |
| 1626 | + continue |
| 1627 | + # Make sure only one thread is calling tf.io.gfile.glob on the same file |
| 1628 | + # pattern at the same time. The other threads will wait for the lock to be |
| 1629 | + # released, and then use the cached result. |
| 1630 | + with _LIST_SHARD_LOCKS[file_pattern]: |
| 1631 | + result.extend(_list_files_for_glob(file_pattern)) |
| 1632 | + return result |
| 1633 | + |
| 1634 | + |
| 1635 | + |
| 1636 | + |
| 1637 | +@functools.lru_cache(maxsize=1024) |
| 1638 | +def _list_files_for_glob(file_pattern: str) -> list[str]: |
| 1639 | + """Returns a sorted list of files for the given glob file pattern.""" |
| 1640 | + file_names = set(tf.io.gfile.glob(file_pattern)) |
| 1641 | + return sorted(file_names) |
| 1642 | + |
| 1643 | + |
0 commit comments