blob: 63b25d5d54c9b934a9d9d41fa4cb32cdba77af15 [file] [log] [blame]
/*
* Copyright (C) 2018 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/storage_schema.h"
#include "src/trace_processor/row_iterators.h"
namespace perfetto {
namespace trace_processor {
StorageSchema::StorageSchema() = default;
StorageSchema::StorageSchema(std::vector<std::unique_ptr<Column>> columns)
: columns_(std::move(columns)) {}
Table::Schema StorageSchema::ToTableSchema(std::vector<std::string> pkeys) {
std::vector<Table::Column> columns;
size_t i = 0;
for (const auto& col : columns_)
columns.emplace_back(i++, col->name(), col->GetType(), col->hidden());
std::vector<size_t> primary_keys;
for (const auto& p_key : pkeys)
primary_keys.emplace_back(ColumnIndexFromName(p_key));
return Table::Schema(std::move(columns), std::move(primary_keys));
}
size_t StorageSchema::ColumnIndexFromName(const std::string& name) {
auto p = [name](const std::unique_ptr<Column>& col) {
return name == col->name();
};
auto it = std::find_if(columns_.begin(), columns_.end(), p);
return static_cast<size_t>(std::distance(columns_.begin(), it));
}
StorageSchema::Column::Column(std::string col_name, bool hidden)
: col_name_(col_name), hidden_(hidden) {}
StorageSchema::Column::~Column() = default;
StorageSchema::TsEndColumn::TsEndColumn(std::string col_name,
const std::deque<uint64_t>* ts_start,
const std::deque<uint64_t>* dur)
: Column(col_name, false), ts_start_(ts_start), dur_(dur) {}
StorageSchema::TsEndColumn::~TsEndColumn() = default;
void StorageSchema::TsEndColumn::ReportResult(sqlite3_context* ctx,
uint32_t row) const {
uint64_t add = (*ts_start_)[row] + (*dur_)[row];
sqlite3_result_int64(ctx, static_cast<sqlite3_int64>(add));
}
StorageSchema::Column::Bounds StorageSchema::TsEndColumn::BoundFilter(
int,
sqlite3_value*) const {
Bounds bounds;
bounds.max_idx = static_cast<uint32_t>(ts_start_->size());
return bounds;
}
StorageSchema::Column::Predicate StorageSchema::TsEndColumn::Filter(
int op,
sqlite3_value* value) const {
auto bipredicate = sqlite_utils::GetPredicateForOp<uint64_t>(op);
uint64_t extracted = sqlite_utils::ExtractSqliteValue<uint64_t>(value);
return [this, bipredicate, extracted](uint32_t idx) {
uint64_t add = (*ts_start_)[idx] + (*dur_)[idx];
return bipredicate(add, extracted);
};
}
StorageSchema::Column::Comparator StorageSchema::TsEndColumn::Sort(
const QueryConstraints::OrderBy& ob) const {
if (ob.desc) {
return [this](uint32_t f, uint32_t s) {
uint64_t a = (*ts_start_)[f] + (*dur_)[f];
uint64_t b = (*ts_start_)[s] + (*dur_)[s];
return sqlite_utils::CompareValuesDesc(a, b);
};
}
return [this](uint32_t f, uint32_t s) {
uint64_t a = (*ts_start_)[f] + (*dur_)[f];
uint64_t b = (*ts_start_)[s] + (*dur_)[s];
return sqlite_utils::CompareValuesAsc(a, b);
};
}
} // namespace trace_processor
} // namespace perfetto