blob: ebf60f8d107b69bda3322d64eef6e3afaa3ea804 [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 <zircon/syscalls.h>
#include <random>
#include <vector>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <fs/lazy_dir.h>
#include <fs/vfs.h>
#include <perftest/perftest.h>
#include "assert.h"
#include "src/lib/fxl/strings/string_printf.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;
ASSERT_OK(dir->Lookup(file_names[i], &out));
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});
}
fs::VdirCookie cookie;
while (state->KeepRunning()) {
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