CommonPathPrefix utility: return the largest common subpath

PiperOrigin-RevId: 344193277
Change-Id: I262cf8f44c3d63bf8eaa7db6818d7c204c2b82ee
This commit is contained in:
George Karpenkov 2020-11-24 22:55:22 -08:00 committed by TensorFlower Gardener
parent dc5faccddb
commit ee21279508
4 changed files with 49 additions and 0 deletions

View File

@ -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

View File

@ -450,6 +450,7 @@ cc_library(
":strcat",
":stringpiece",
":types",
"@com_google_absl//absl/algorithm:container",
],
alwayslink = True,
)

View File

@ -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.";

View File

@ -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 "/".
//