blob: a31a7c09b4a7b180ed17f8c8145adba17cb4e0b3 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/trace_processor/metadata_table.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/storage_columns.h"
#include "src/trace_processor/storage_schema.h"
namespace perfetto {
namespace trace_processor {
MetadataTable::MetadataTable(sqlite3*, const TraceStorage* storage)
: storage_(storage) {}
void MetadataTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
SqliteTable::Register<MetadataTable>(db, storage, "metadata");
}
StorageSchema MetadataTable::CreateStorageSchema() {
return StorageSchema::Builder()
.AddColumn<StringColumn<MetadataKeyNameAccessor>>(
"name", &storage_->metadata().keys())
.AddColumn<StringColumn<MetadataKeyTypeAccessor>>(
"key_type", &storage_->metadata().keys())
.AddColumn<ValueColumn>("int_value", Variadic::Type::kInt, storage_)
.AddColumn<ValueColumn>("str_value", Variadic::Type::kString, storage_)
.Build({"name"});
}
uint32_t MetadataTable::RowCount() {
return static_cast<uint32_t>(storage_->metadata().keys().size());
}
int MetadataTable::BestIndex(const QueryConstraints&, BestIndexInfo*) {
return SQLITE_OK;
}
MetadataTable::MetadataKeyNameAccessor::MetadataKeyNameAccessor(
const std::deque<metadata::KeyIDs>* keys)
: keys_(keys) {}
MetadataTable::MetadataKeyNameAccessor::~MetadataKeyNameAccessor() = default;
MetadataTable::MetadataKeyTypeAccessor::MetadataKeyTypeAccessor(
const std::deque<metadata::KeyIDs>* keys)
: keys_(keys) {}
MetadataTable::MetadataKeyTypeAccessor::~MetadataKeyTypeAccessor() = default;
MetadataTable::ValueColumn::ValueColumn(std::string col_name,
Variadic::Type type,
const TraceStorage* storage)
: StorageColumn(col_name, false /* hidden */),
type_(type),
storage_(storage) {
PERFETTO_CHECK(type == Variadic::Type::kInt ||
type == Variadic::Type::kString);
}
void MetadataTable::ValueColumn::ReportResult(sqlite3_context* ctx,
uint32_t row) const {
const auto& metadata = storage_->metadata();
auto value_type = metadata::kValueTypes[metadata.keys()[row]];
if (value_type != type_) {
sqlite3_result_null(ctx);
return;
}
if (value_type == Variadic::Type::kInt) {
sqlite_utils::ReportSqliteResult(ctx, metadata.values()[row].int_value);
return;
}
if (value_type == Variadic::Type::kString) {
const char* str =
storage_->GetString(metadata.values()[row].string_value).c_str();
sqlite3_result_text(ctx, str, -1, sqlite_utils::kSqliteStatic);
return;
}
PERFETTO_FATAL("Unimplemented metadata value type.");
}
MetadataTable::ValueColumn::Bounds MetadataTable::ValueColumn::BoundFilter(
int,
sqlite3_value*) const {
return Bounds{};
}
void MetadataTable::ValueColumn::Filter(int op,
sqlite3_value* value,
FilteredRowIndex* index) const {
if (type_ == Variadic::Type::kInt) {
bool op_is_null = sqlite_utils::IsOpIsNull(op);
auto predicate = sqlite_utils::CreateNumericPredicate<int64_t>(op, value);
index->FilterRows(
[this, predicate, op_is_null](uint32_t row) PERFETTO_ALWAYS_INLINE {
const auto& arg = storage_->metadata().values()[row];
return arg.type == type_ ? predicate(arg.int_value) : op_is_null;
});
return;
}
if (type_ == Variadic::Type::kString) {
auto predicate = sqlite_utils::CreateStringPredicate(op, value);
index->FilterRows([this, &predicate](uint32_t row) PERFETTO_ALWAYS_INLINE {
const auto& arg = storage_->metadata().values()[row];
return arg.type == type_
? predicate(storage_->GetString(arg.string_value).c_str())
: predicate(nullptr);
});
return;
}
PERFETTO_FATAL("Unimplemented metadata value type.");
}
MetadataTable::ValueColumn::Comparator MetadataTable::ValueColumn::Sort(
const QueryConstraints::OrderBy& ob) const {
if (ob.desc) {
return [this](uint32_t f, uint32_t s) { return -CompareRefsAsc(f, s); };
}
return [this](uint32_t f, uint32_t s) { return CompareRefsAsc(f, s); };
}
int MetadataTable::ValueColumn::CompareRefsAsc(uint32_t f, uint32_t s) const {
const auto& arg_f = storage_->metadata().values()[f];
const auto& arg_s = storage_->metadata().values()[s];
if (arg_f.type == type_ && arg_s.type == type_) {
if (type_ == Variadic::Type::kInt) {
return sqlite_utils::CompareValuesAsc(arg_f.int_value, arg_s.int_value);
}
if (type_ == Variadic::Type::kString) {
const auto& f_str = storage_->GetString(arg_f.string_value);
const auto& s_str = storage_->GetString(arg_s.string_value);
return sqlite_utils::CompareValuesAsc(f_str, s_str);
}
PERFETTO_FATAL("Unimplemented metadata value type.");
} else if (arg_s.type == type_) {
return -1;
} else if (arg_f.type == type_) {
return 1;
}
return 0;
}
} // namespace trace_processor
} // namespace perfetto