-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[disk cache] Introduce a class to traverse a directory
Split disk_cache::SimpleIndexFile::TraverseCacheDirectory into a separate class so that we can use it from outside of disk cache easily. Bug: 1289542 Change-Id: I3070e28efed065cafc077c5af7946a71de90f324 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3569143 Commit-Queue: Yutaka Hirano <yhirano@chromium.org> Reviewed-by: Maks Orlovich <morlovich@chromium.org> Cr-Commit-Position: refs/heads/main@{#988928}
- Loading branch information
1 parent
56e6876
commit 8921372
Showing
10 changed files
with
239 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hello |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hello, world |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "net/disk_cache/simple/simple_file_enumerator.h" | ||
|
||
#include "base/files/file.h" | ||
#include "base/files/file_util.h" | ||
#include "base/logging.h" | ||
|
||
using Entry = disk_cache::SimpleFileEnumerator::Entry; | ||
|
||
// We have an optimized implementation for POSIX, and a fallback | ||
// implementation for other platforms. | ||
|
||
namespace disk_cache { | ||
|
||
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) | ||
|
||
SimpleFileEnumerator::SimpleFileEnumerator(const base::FilePath& path) | ||
: path_(path), dir_(opendir(path.value().c_str())), has_error_(!dir_) { | ||
if (has_error_) { | ||
PLOG(ERROR) << "opendir " << path; | ||
} | ||
} | ||
SimpleFileEnumerator::~SimpleFileEnumerator() = default; | ||
|
||
bool SimpleFileEnumerator::HasError() const { | ||
return has_error_; | ||
} | ||
|
||
absl::optional<Entry> SimpleFileEnumerator::Next() { | ||
if (!dir_) { | ||
return absl::nullopt; | ||
} | ||
while (true) { | ||
// errno must be set to 0 before every readdir() call to detect errors. | ||
errno = 0; | ||
dirent* entry = readdir(dir_.get()); | ||
if (!entry) { | ||
// Some implementations of readdir() (particularly older versions of | ||
// Android Bionic) may leave errno set to EINTR even after they handle | ||
// this case internally. It's safe to ignore EINTR in that case. | ||
if (errno && errno != EINTR) { | ||
PLOG(ERROR) << "readdir " << path_; | ||
has_error_ = true; | ||
dir_ = nullptr; | ||
return absl::nullopt; | ||
} | ||
break; | ||
} | ||
|
||
const std::string filename(entry->d_name); | ||
if (filename == "." || filename == "..") { | ||
continue; | ||
} | ||
base::FilePath path = path_.Append(base::FilePath(filename)); | ||
base::File::Info file_info; | ||
if (!base::GetFileInfo(path, &file_info)) { | ||
LOG(ERROR) << "Could not get file info for " << path; | ||
continue; | ||
} | ||
if (file_info.is_directory) { | ||
continue; | ||
} | ||
return absl::make_optional<Entry>(std::move(path), file_info.size, | ||
file_info.last_accessed, | ||
file_info.last_modified); | ||
} | ||
dir_ = nullptr; | ||
return absl::nullopt; | ||
} | ||
|
||
#else | ||
SimpleFileEnumerator::SimpleFileEnumerator(const base::FilePath& path) | ||
: enumerator_(path, | ||
/*recursive=*/false, | ||
base::FileEnumerator::FILES) {} | ||
SimpleFileEnumerator::~SimpleFileEnumerator() = default; | ||
|
||
bool SimpleFileEnumerator::HasError() const { | ||
return enumerator_.GetError() != base::File::FILE_OK; | ||
} | ||
|
||
absl::optional<Entry> SimpleFileEnumerator::Next() { | ||
base::FilePath path = enumerator_.Next(); | ||
if (path.empty()) { | ||
return absl::nullopt; | ||
} | ||
base::FileEnumerator::FileInfo info = enumerator_.GetInfo(); | ||
return absl::make_optional<Entry>(std::move(path), info.GetSize(), | ||
/*last_accessed=*/base::Time(), | ||
info.GetLastModifiedTime()); | ||
} | ||
#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) | ||
|
||
} // namespace disk_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_ENUMERATOR_H_ | ||
#define NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_ENUMERATOR_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/files/file_path.h" | ||
#include "base/time/time.h" | ||
#include "build/build_config.h" | ||
#include "net/base/net_export.h" | ||
#include "third_party/abseil-cpp/absl/types/optional.h" | ||
|
||
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) | ||
#include <dirent.h> | ||
#include <sys/types.h> | ||
#else | ||
#include "base/files/file_enumerator.h" | ||
#endif | ||
|
||
namespace disk_cache { | ||
|
||
// This is similar to base::SimpleFileEnumerator, but the implementation is | ||
// optimized for the big directory use-case on POSIX. See | ||
// https://crbug.com/270762 and https://codereview.chromium.org/22927018. | ||
class NET_EXPORT SimpleFileEnumerator final { | ||
public: | ||
explicit SimpleFileEnumerator(const base::FilePath& root_path); | ||
~SimpleFileEnumerator(); | ||
|
||
struct Entry { | ||
Entry(base::FilePath path, | ||
int64_t size, | ||
base::Time last_accessed, | ||
base::Time last_modified) | ||
: path(std::move(path)), | ||
size(size), | ||
last_accessed(last_accessed), | ||
last_modified(last_modified) {} | ||
|
||
base::FilePath path; | ||
int64_t size; | ||
base::Time last_accessed; | ||
base::Time last_modified; | ||
}; | ||
|
||
// Returns true if we've found an error during enumeration. | ||
bool HasError() const; | ||
|
||
// Returns the next item, or nullopt if there are no more results (including | ||
// the error case). | ||
absl::optional<Entry> Next(); | ||
|
||
private: | ||
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) | ||
struct DirCloser { | ||
void operator()(DIR* dir) { closedir(dir); } | ||
}; | ||
const base::FilePath path_; | ||
std::unique_ptr<DIR, DirCloser> dir_; | ||
bool has_error_ = false; | ||
#else | ||
base::FileEnumerator enumerator_; | ||
#endif | ||
}; | ||
|
||
} // namespace disk_cache | ||
|
||
#endif // NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_ENUMERATOR_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "net/disk_cache/simple/simple_file_enumerator.h" | ||
|
||
#include "base/path_service.h" | ||
#include "net/test/gtest_util.h" | ||
#include "net/test/test_with_task_environment.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace disk_cache { | ||
namespace { | ||
|
||
using Entry = SimpleFileEnumerator::Entry; | ||
|
||
base::FilePath GetRoot() { | ||
base::FilePath root; | ||
base::PathService::Get(base::DIR_SOURCE_ROOT, &root); | ||
return root.AppendASCII("net") | ||
.AppendASCII("data") | ||
.AppendASCII("cache_tests") | ||
.AppendASCII("simple_file_enumerator"); | ||
} | ||
|
||
TEST(SimpleFileEnumeratorTest, Root) { | ||
const base::FilePath kRoot = GetRoot(); | ||
SimpleFileEnumerator enumerator(kRoot); | ||
|
||
auto entry = enumerator.Next(); | ||
ASSERT_TRUE(entry.has_value()); | ||
EXPECT_EQ(entry->path, kRoot.AppendASCII("test.txt")); | ||
EXPECT_EQ(entry->size, 13); | ||
EXPECT_FALSE(enumerator.HasError()); | ||
|
||
// No directories should be listed, no indirect descendants should be listed. | ||
EXPECT_EQ(absl::nullopt, enumerator.Next()); | ||
EXPECT_FALSE(enumerator.HasError()); | ||
|
||
// We can call enumerator.Next() after the iteration is done. | ||
EXPECT_EQ(absl::nullopt, enumerator.Next()); | ||
EXPECT_FALSE(enumerator.HasError()); | ||
} | ||
|
||
TEST(SimpleFileEnumeratorTest, NotFound) { | ||
const base::FilePath kRoot = GetRoot().AppendASCII("not-found"); | ||
SimpleFileEnumerator enumerator(kRoot); | ||
|
||
auto entry = enumerator.Next(); | ||
EXPECT_EQ(absl::nullopt, enumerator.Next()); | ||
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) | ||
EXPECT_TRUE(enumerator.HasError()); | ||
#endif | ||
} | ||
|
||
} // namespace | ||
} // namespace disk_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.