CommonPathPrefix utility: return the largest common subpath
PiperOrigin-RevId: 344193277 Change-Id: I262cf8f44c3d63bf8eaa7db6818d7c204c2b82ee
This commit is contained in:
parent
dc5faccddb
commit
ee21279508
@ -141,5 +141,14 @@ TEST(PathTest, CreateParseURI) {
|
||||
}
|
||||
#undef EXPECT_PARSE_URI
|
||||
|
||||
TEST(PathTest, CommonPathPrefix) {
|
||||
EXPECT_EQ(CommonPathPrefix({"/alpha/beta/c", "/alpha/beta/g"}),
|
||||
"/alpha/beta/");
|
||||
EXPECT_EQ(CommonPathPrefix({"/a/b/c", "/a/beta/gamma"}), "/a/");
|
||||
EXPECT_EQ(CommonPathPrefix({}), "");
|
||||
EXPECT_EQ(CommonPathPrefix({"/a/b/c", "", "/a/b/"}), "");
|
||||
EXPECT_EQ(CommonPathPrefix({"alpha", "alphabeta"}), "");
|
||||
}
|
||||
|
||||
} // namespace io
|
||||
} // namespace tensorflow
|
||||
|
@ -450,6 +450,7 @@ cc_library(
|
||||
":strcat",
|
||||
":stringpiece",
|
||||
":types",
|
||||
"@com_google_absl//absl/algorithm:container",
|
||||
],
|
||||
alwayslink = True,
|
||||
)
|
||||
|
@ -28,6 +28,7 @@ limitations under the License.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "tensorflow/core/platform/logging.h"
|
||||
#include "tensorflow/core/platform/mutex.h"
|
||||
#include "tensorflow/core/platform/scanner.h"
|
||||
@ -273,6 +274,35 @@ int64 UniqueId() {
|
||||
return ++id;
|
||||
}
|
||||
|
||||
string CommonPathPrefix(absl::Span<const string> paths) {
|
||||
if (paths.empty()) return "";
|
||||
size_t min_filename_size =
|
||||
absl::c_min_element(paths, [](const string& a, const string& b) {
|
||||
return a.size() < b.size();
|
||||
})->size();
|
||||
if (min_filename_size == 0) return "";
|
||||
|
||||
size_t common_prefix_size = [&] {
|
||||
for (size_t prefix_size = 0; prefix_size < min_filename_size;
|
||||
prefix_size++) {
|
||||
char c = paths[0][prefix_size];
|
||||
for (int f = 1; f < paths.size(); f++) {
|
||||
if (paths[f][prefix_size] != c) {
|
||||
return prefix_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
return min_filename_size;
|
||||
}();
|
||||
|
||||
size_t rpos = absl::string_view(paths[0])
|
||||
.substr(0, common_prefix_size)
|
||||
.rfind(internal::kPathSep);
|
||||
return rpos == std::string::npos
|
||||
? ""
|
||||
: std::string(absl::string_view(paths[0]).substr(0, rpos + 1));
|
||||
}
|
||||
|
||||
string GetTempFilename(const string& extension) {
|
||||
#if defined(__ANDROID__)
|
||||
LOG(FATAL) << "GetTempFilename is not implemented in this platform.";
|
||||
|
@ -64,6 +64,15 @@ tensorflow::StringPiece Basename(tensorflow::StringPiece path);
|
||||
// there is no "." in the basename, the result is empty.
|
||||
tensorflow::StringPiece Extension(tensorflow::StringPiece path);
|
||||
|
||||
// Returns the largest common subpath of `paths`.
|
||||
//
|
||||
// For example, for "/alpha/beta/gamma" and "/alpha/beta/ga" returns
|
||||
// "/alpha/beta/". For "/alpha/beta/gamma" and "/alpha/beta/gamma" returns
|
||||
// "/alpha/beta/".
|
||||
//
|
||||
// Does not perform any path normalization.
|
||||
string CommonPathPrefix(absl::Span<string const> paths);
|
||||
|
||||
// Collapse duplicate "/"s, resolve ".." and "." path elements, remove
|
||||
// trailing "/".
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user