blob: 9b846d9ee4ac28c9eb314db001d89dd551e4d5f1 [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 <random>
#include <vector>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <fs/lazy-dir.h>
#include <fs/vfs.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <perftest/perftest.h>
#include <zircon/syscalls.h>
#include "util.h"
namespace {
class TestLazyDir : public fs::LazyDir {
public:
void AddEntry(LazyEntry entry) { entries_.push_back(std::move(entry)); }
protected:
void GetContents(LazyEntryVector* out_vector) override {
out_vector->reserve(entries_.size());
for (const auto& entry : entries_) {
out_vector->push_back(entry);
}
}
zx_status_t GetFile(fbl::RefPtr<Vnode>* out_vnode, uint64_t id,
fbl::String name) override {
// Do nothing to benchmark obtaining id and name.
return ZX_OK;
}
fbl::Vector<LazyEntry> entries_;
};
// Measure the time taken to create an empty LazyDir.
bool TestCreate(perftest::RepeatState* state) {
while (state->KeepRunning()) {
ZX_ASSERT(fbl::AdoptRef<TestLazyDir>(new TestLazyDir()) != nullptr);
}
return true;
}
// Measure the time taken to look up an entry in a LazyDir of a given size.
bool TestLookup(perftest::RepeatState* state, size_t file_count) {
auto file_names = util::MakeDeterministicNamesList(file_count);
auto dir = fbl::AdoptRef(new TestLazyDir());
uint64_t id = 1;
for (const auto& name : file_names) {
dir->AddEntry({id++, name, V_TYPE_FILE});
}
int i = 0;
while (state->KeepRunning()) {
fbl::RefPtr<fs::Vnode> out;
ZX_ASSERT(dir->Lookup(&out, file_names[i]) == ZX_OK);
i = (i + 1) % file_names.size();
}
return true;
}
// Measure the time taken to read directory entries from a LazyDir of
// a given size using a given sized buffer.
bool TestReaddir(perftest::RepeatState* state, size_t file_count,
size_t buffer_size) {
auto file_names = util::MakeDeterministicNamesList(file_count);
std::vector<char> buffer(buffer_size);
auto dir = fbl::AdoptRef(new TestLazyDir());
uint64_t id = 1;
for (const auto& name : file_names) {
dir->AddEntry({id++, name, V_TYPE_FILE});
}
while (state->KeepRunning()) {
fs::vdircookie_t cookie;
size_t real_len = 0;
while (dir->Readdir(&cookie, buffer.data(), buffer_size, &real_len) !=
ZX_OK) {
ZX_ASSERT(real_len != 0);
}
}
return true;
}
void RegisterTests() {
static const size_t kSizes[] = {1, 8, 64, 512, 4 * 1024, 16 * 1024};
static const size_t kBuffers[] = {1024, 4 * 1024, 16 * 1024, 64 * 1024};
perftest::RegisterTest("LazyDir/Create", TestCreate);
for (auto size : kSizes) {
auto name = fbl::StringPrintf("LazyDir/Lookup/size:%zd", size);
perftest::RegisterTest(name.c_str(), TestLookup, size);
}
for (auto size : kSizes) {
for (auto buffer : kBuffers) {
auto name =
fbl::StringPrintf("LazyDir/Readdir/size:%zd/buf:%zd", size, buffer);
perftest::RegisterTest(name.c_str(), TestReaddir, size, buffer);
}
}
}
PERFTEST_CTOR(RegisterTests);
} // namespace