tp: decouple nullable vector from column storage
This allows for splitting nullable vs non-nullable storage in a follow
up CL.
Bug: 235104800
Change-Id: I168f907318104bb82588271c38817af52d2d3dd3
diff --git a/Android.bp b/Android.bp
index 9d91a4e..7378bad 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8241,7 +8241,6 @@
srcs: [
"src/trace_processor/containers/bit_vector.cc",
"src/trace_processor/containers/bit_vector_iterators.cc",
- "src/trace_processor/containers/nullable_vector.cc",
"src/trace_processor/containers/row_map.cc",
"src/trace_processor/containers/string_pool.cc",
],
@@ -8264,6 +8263,7 @@
name: "perfetto_src_trace_processor_db_db",
srcs: [
"src/trace_processor/db/column.cc",
+ "src/trace_processor/db/column_storage.cc",
"src/trace_processor/db/table.cc",
"src/trace_processor/db/view.cc",
],
diff --git a/BUILD b/BUILD
index 0c50584..7d2bfaf 100644
--- a/BUILD
+++ b/BUILD
@@ -958,7 +958,6 @@
srcs = [
"src/trace_processor/containers/bit_vector.cc",
"src/trace_processor/containers/bit_vector_iterators.cc",
- "src/trace_processor/containers/nullable_vector.cc",
"src/trace_processor/containers/row_map.cc",
"src/trace_processor/containers/string_pool.cc",
],
@@ -988,6 +987,8 @@
"src/trace_processor/db/base_id.h",
"src/trace_processor/db/column.cc",
"src/trace_processor/db/column.h",
+ "src/trace_processor/db/column_storage.cc",
+ "src/trace_processor/db/column_storage.h",
"src/trace_processor/db/compare.h",
"src/trace_processor/db/table.cc",
"src/trace_processor/db/table.h",
diff --git a/src/trace_processor/containers/BUILD.gn b/src/trace_processor/containers/BUILD.gn
index 1e92c62..e4750d2 100644
--- a/src/trace_processor/containers/BUILD.gn
+++ b/src/trace_processor/containers/BUILD.gn
@@ -32,7 +32,6 @@
sources = [
"bit_vector.cc",
"bit_vector_iterators.cc",
- "nullable_vector.cc",
"row_map.cc",
"string_pool.cc",
]
diff --git a/src/trace_processor/containers/bit_vector.cc b/src/trace_processor/containers/bit_vector.cc
index f2d14e8..ca523d5 100644
--- a/src/trace_processor/containers/bit_vector.cc
+++ b/src/trace_processor/containers/bit_vector.cc
@@ -16,6 +16,8 @@
#include "src/trace_processor/containers/bit_vector.h"
+#include <limits>
+
#include "src/trace_processor/containers/bit_vector_iterators.h"
#if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
diff --git a/src/trace_processor/containers/nullable_vector.h b/src/trace_processor/containers/nullable_vector.h
index 44bf4f6..cb97492 100644
--- a/src/trace_processor/containers/nullable_vector.h
+++ b/src/trace_processor/containers/nullable_vector.h
@@ -28,20 +28,6 @@
namespace perfetto {
namespace trace_processor {
-// Base class for NullableVector which allows type erasure to be implemented
-// (e.g. allows for std::unique_ptr<NullableVectorBase>).
-class NullableVectorBase {
- public:
- NullableVectorBase() = default;
- virtual ~NullableVectorBase();
-
- NullableVectorBase(const NullableVectorBase&) = delete;
- NullableVectorBase& operator=(const NullableVectorBase&) = delete;
-
- NullableVectorBase(NullableVectorBase&&) = default;
- NullableVectorBase& operator=(NullableVectorBase&&) noexcept = default;
-};
-
// A data structure which compactly stores a list of possibly nullable data.
//
// Internally, this class is implemented using a combination of a std::deque
@@ -50,7 +36,7 @@
// BitVector at a slight cost (searching the BitVector to find the index into
// the std::deque) when looking up the data.
template <typename T>
-class NullableVector : public NullableVectorBase {
+class NullableVector {
private:
enum class Mode {
// Sparse mode is the default mode and ensures that nulls are stored using
@@ -68,9 +54,8 @@
public:
// Creates an empty NullableVector.
NullableVector() : NullableVector<T>(Mode::kSparse) {}
- ~NullableVector() override = default;
- explicit NullableVector(const NullableVector&) = delete;
+ NullableVector(const NullableVector&) = delete;
NullableVector& operator=(const NullableVector&) = delete;
NullableVector(NullableVector&&) = default;
diff --git a/src/trace_processor/db/BUILD.gn b/src/trace_processor/db/BUILD.gn
index f118943..539cde3 100644
--- a/src/trace_processor/db/BUILD.gn
+++ b/src/trace_processor/db/BUILD.gn
@@ -19,6 +19,8 @@
"base_id.h",
"column.cc",
"column.h",
+ "column_storage.cc",
+ "column_storage.h",
"compare.h",
"table.cc",
"table.h",
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index 98602c4..8c8842b 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -33,7 +33,7 @@
table,
col_idx,
row_map_idx,
- column.nullable_vector_) {}
+ column.storage_) {}
Column::Column(const char* name,
ColumnType type,
@@ -41,9 +41,9 @@
Table* table,
uint32_t col_idx_in_table,
uint32_t row_map_idx,
- NullableVectorBase* nv)
+ ColumnStorageBase* st)
: type_(type),
- nullable_vector_(nv),
+ storage_(st),
name_(name),
flags_(flags),
table_(table),
@@ -51,25 +51,29 @@
row_map_idx_(row_map_idx),
string_pool_(table->string_pool_) {
// Check that the dense-ness of the column and the nullable vector match.
- switch (type_) {
- case ColumnType::kInt32:
- PERFETTO_DCHECK(nullable_vector<int32_t>().IsDense() == IsDense());
- break;
- case ColumnType::kUint32:
- PERFETTO_DCHECK(nullable_vector<uint32_t>().IsDense() == IsDense());
- break;
- case ColumnType::kInt64:
- PERFETTO_DCHECK(nullable_vector<int64_t>().IsDense() == IsDense());
- break;
- case ColumnType::kDouble:
- PERFETTO_DCHECK(nullable_vector<double>().IsDense() == IsDense());
- break;
- case ColumnType::kString:
- PERFETTO_DCHECK(nullable_vector<StringPool::Id>().IsDense() == IsDense());
- break;
- case ColumnType::kId:
- case ColumnType::kDummy:
- break;
+ if (IsNullable() && !IsDummy()) {
+ bool is_storage_dense;
+ switch (type_) {
+ case ColumnType::kInt32:
+ is_storage_dense = storage<int32_t>().IsDense();
+ break;
+ case ColumnType::kUint32:
+ is_storage_dense = storage<uint32_t>().IsDense();
+ break;
+ case ColumnType::kInt64:
+ is_storage_dense = storage<int64_t>().IsDense();
+ break;
+ case ColumnType::kDouble:
+ is_storage_dense = storage<double>().IsDense();
+ break;
+ case ColumnType::kString:
+ PERFETTO_FATAL("String column should not be nullable");
+ case ColumnType::kId:
+ PERFETTO_FATAL("Id column should not be nullable");
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("Dummy column excluded above");
+ }
+ PERFETTO_DCHECK(is_storage_dense == IsDense());
}
PERFETTO_DCHECK(IsFlagsAndTypeValid(flags_, type_));
}
@@ -154,7 +158,7 @@
PERFETTO_DCHECK(value.is_null());
if (is_nullable) {
row_map().FilterInto(rm, [this](uint32_t row) {
- return !nullable_vector<T>().Get(row).has_value();
+ return !storage<T>().Get(row).has_value();
});
} else {
rm->Clear();
@@ -164,7 +168,7 @@
PERFETTO_DCHECK(value.is_null());
if (is_nullable) {
row_map().FilterInto(rm, [this](uint32_t row) {
- return nullable_vector<T>().Get(row).has_value();
+ return storage<T>().Get(row).has_value();
});
}
return;
@@ -222,55 +226,55 @@
case FilterOp::kLt:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) < 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) < 0;
+ return cmp(storage<T>().GetNonNull(idx)) < 0;
});
break;
case FilterOp::kEq:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) == 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) == 0;
+ return cmp(storage<T>().GetNonNull(idx)) == 0;
});
break;
case FilterOp::kGt:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) > 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) > 0;
+ return cmp(storage<T>().GetNonNull(idx)) > 0;
});
break;
case FilterOp::kNe:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) != 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) != 0;
+ return cmp(storage<T>().GetNonNull(idx)) != 0;
});
break;
case FilterOp::kLe:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) <= 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) <= 0;
+ return cmp(storage<T>().GetNonNull(idx)) <= 0;
});
break;
case FilterOp::kGe:
row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
if (is_nullable) {
- auto opt_value = nullable_vector<T>().Get(idx);
+ auto opt_value = storage<T>().Get(idx);
return opt_value && cmp(*opt_value) >= 0;
}
- return cmp(nullable_vector<T>().GetNonNull(idx)) >= 0;
+ return cmp(storage<T>().GetNonNull(idx)) >= 0;
});
break;
case FilterOp::kIsNull:
@@ -465,20 +469,19 @@
PERFETTO_DCHECK(IsNullable() == is_nullable);
PERFETTO_DCHECK(ColumnTypeHelper<T>::ToColumnType() == type_);
- const auto& nv = nullable_vector<T>();
- row_map().StableSort(out, [&nv](uint32_t a_idx, uint32_t b_idx) {
+ row_map().StableSort(out, [this](uint32_t a_idx, uint32_t b_idx) {
if (is_nullable) {
- auto a_val = nv.Get(a_idx);
- auto b_val = nv.Get(b_idx);
+ auto a_val = storage<T>().Get(a_idx);
+ auto b_val = storage<T>().Get(b_idx);
int res = compare::NullableNumeric(a_val, b_val);
return desc ? res > 0 : res < 0;
}
- auto a_val = nv.GetNonNull(a_idx);
- auto b_val = nv.GetNonNull(b_idx);
+ auto a_val = storage<T>().GetNonNull(a_idx);
+ auto b_val = storage<T>().GetNonNull(b_idx);
- return desc ? compare::Numeric(a_val, b_val) > 0
- : compare::Numeric(a_val, b_val) < 0;
+ int res = compare::Numeric(a_val, b_val);
+ return desc ? res > 0 : res < 0;
});
}
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index f83e56e..dd4a8f5 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -22,10 +22,11 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/containers/nullable_vector.h"
#include "src/trace_processor/containers/row_map.h"
#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/db/column_storage.h"
#include "src/trace_processor/db/compare.h"
+#include "src/trace_processor/db/typed_column_internal.h"
namespace perfetto {
namespace trace_processor {
@@ -218,7 +219,7 @@
template <typename T>
Column(const char* name,
- NullableVector<T>* storage,
+ ColumnStorage<T>* storage,
/* Flag */ uint32_t flags,
Table* table,
uint32_t col_idx_in_table,
@@ -435,26 +436,23 @@
}
protected:
+ template <typename T>
+ using storage_t = typename tc_internal::TypeHandler<T>::storage_type;
+
// Returns the backing sparse vector cast to contain data of type T.
// Should only be called when |type_| == ToColumnType<T>().
template <typename T>
- NullableVector<T>* mutable_nullable_vector() {
+ storage_t<T>* mutable_storage() {
PERFETTO_DCHECK(ColumnTypeHelper<T>::ToColumnType() == type_);
- return static_cast<NullableVector<T>*>(nullable_vector_);
+ return static_cast<storage_t<T>*>(storage_);
}
// Returns the backing sparse vector cast to contain data of type T.
// Should only be called when |type_| == ToColumnType<T>().
template <typename T>
- const NullableVector<T>& nullable_vector() const {
+ const storage_t<T>& storage() const {
PERFETTO_DCHECK(ColumnTypeHelper<T>::ToColumnType() == type_);
- return *static_cast<const NullableVector<T>*>(nullable_vector_);
- }
-
- // Returns the type of this Column in terms of SqlValue::Type.
- template <typename T>
- static SqlValue::Type ToSqlValueType() {
- return ToSqlValueType(ColumnTypeHelper<T>::ToColumnType());
+ return *static_cast<storage_t<T>*>(storage_);
}
// Returns true if this column is a dense column.
@@ -465,6 +463,20 @@
const StringPool& string_pool() const { return *string_pool_; }
+ // Returns the type of this Column in terms of SqlValue::Type.
+ template <typename T>
+ static SqlValue::Type ToSqlValueType() {
+ return ToSqlValueType(ColumnTypeHelper<T>::ToColumnType());
+ }
+
+ static SqlValue ToSqlValue(double value) { return SqlValue::Double(value); }
+ static SqlValue ToSqlValue(int32_t value) { return SqlValue::Long(value); }
+ static SqlValue ToSqlValue(uint32_t value) { return SqlValue::Long(value); }
+ static SqlValue ToSqlValue(int64_t value) { return SqlValue::Long(value); }
+ static SqlValue ToSqlValue(NullTermStringView value) {
+ return SqlValue::String(value.c_str());
+ }
+
private:
friend class Table;
friend class View;
@@ -476,7 +488,7 @@
Table* table,
uint32_t col_idx_in_table,
uint32_t row_map_idx,
- NullableVectorBase* nullable_vector);
+ ColumnStorageBase* nullable_vector);
Column(const Column&) = delete;
Column& operator=(const Column&) = delete;
@@ -484,22 +496,14 @@
// Gets the value of the Column at the given |idx|.
SqlValue GetAtIdx(uint32_t idx) const {
switch (type_) {
- case ColumnType::kInt32: {
- auto opt_value = nullable_vector<int32_t>().Get(idx);
- return opt_value ? SqlValue::Long(*opt_value) : SqlValue();
- }
- case ColumnType::kUint32: {
- auto opt_value = nullable_vector<uint32_t>().Get(idx);
- return opt_value ? SqlValue::Long(*opt_value) : SqlValue();
- }
- case ColumnType::kInt64: {
- auto opt_value = nullable_vector<int64_t>().Get(idx);
- return opt_value ? SqlValue::Long(*opt_value) : SqlValue();
- }
- case ColumnType::kDouble: {
- auto opt_value = nullable_vector<double>().Get(idx);
- return opt_value ? SqlValue::Double(*opt_value) : SqlValue();
- }
+ case ColumnType::kInt32:
+ return GetAtIdxTyped<int32_t>(idx);
+ case ColumnType::kUint32:
+ return GetAtIdxTyped<uint32_t>(idx);
+ case ColumnType::kInt64:
+ return GetAtIdxTyped<int64_t>(idx);
+ case ColumnType::kDouble:
+ return GetAtIdxTyped<double>(idx);
case ColumnType::kString: {
auto str = GetStringPoolStringAtIdx(idx).c_str();
return str == nullptr ? SqlValue() : SqlValue::String(str);
@@ -512,6 +516,15 @@
PERFETTO_FATAL("For GCC");
}
+ template <typename T>
+ SqlValue GetAtIdxTyped(uint32_t idx) const {
+ if (IsNullable()) {
+ auto opt_value = storage<T>().Get(idx);
+ return opt_value ? ToSqlValue(*opt_value) : SqlValue();
+ }
+ return ToSqlValue(storage<T>().GetNonNull(idx));
+ }
+
// Optimized filter method for sorted columns.
// Returns whether the constraint was handled by the method.
bool FilterIntoSorted(FilterOp op, SqlValue value, RowMap* rm) const {
@@ -565,7 +578,7 @@
PERFETTO_DCHECK(!IsNullable());
uint32_t filter_set_id = static_cast<uint32_t>(value);
- const auto& nv = nullable_vector<uint32_t>();
+ const auto& nv = storage<uint32_t>();
const RowMap& col_rm = row_map();
// If the set id is beyond the end of the column, there's no chance that
@@ -676,12 +689,12 @@
// Should only be called when |type_| == ColumnType::kString.
NullTermStringView GetStringPoolStringAtIdx(uint32_t idx) const {
PERFETTO_DCHECK(type_ == ColumnType::kString);
- return string_pool_->Get(nullable_vector<StringPool::Id>().GetNonNull(idx));
+ return string_pool_->Get(storage<StringPool::Id>().GetNonNull(idx));
}
// type_ is used to cast nullable_vector_ to the correct type.
ColumnType type_ = ColumnType::kInt64;
- NullableVectorBase* nullable_vector_ = nullptr;
+ ColumnStorageBase* storage_ = nullptr;
const char* name_ = nullptr;
uint32_t flags_ = Flag::kNoFlag;
diff --git a/src/trace_processor/containers/nullable_vector.cc b/src/trace_processor/db/column_storage.cc
similarity index 85%
rename from src/trace_processor/containers/nullable_vector.cc
rename to src/trace_processor/db/column_storage.cc
index 7c4cd68..d1d348f 100644
--- a/src/trace_processor/containers/nullable_vector.cc
+++ b/src/trace_processor/db/column_storage.cc
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include "src/trace_processor/containers/nullable_vector.h"
+#include "src/trace_processor/db/column_storage.h"
namespace perfetto {
namespace trace_processor {
-NullableVectorBase::~NullableVectorBase() = default;
+ColumnStorageBase::~ColumnStorageBase() = default;
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/db/column_storage.h b/src/trace_processor/db/column_storage.h
new file mode 100644
index 0000000..2ba443f
--- /dev/null
+++ b/src/trace_processor/db/column_storage.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_DB_COLUMN_STORAGE_H_
+#define SRC_TRACE_PROCESSOR_DB_COLUMN_STORAGE_H_
+
+#include "src/trace_processor/containers/nullable_vector.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Base class for allowing type erasure when defining plug-in implementations
+// of backing storage for columns.
+class ColumnStorageBase {
+ public:
+ ColumnStorageBase() = default;
+ virtual ~ColumnStorageBase();
+
+ ColumnStorageBase(const ColumnStorageBase&) = delete;
+ ColumnStorageBase& operator=(const ColumnStorageBase&) = delete;
+
+ ColumnStorageBase(ColumnStorageBase&&) = default;
+ ColumnStorageBase& operator=(ColumnStorageBase&&) noexcept = default;
+};
+
+// Class used for implementing storage for columns.
+// TODO(lalitm): split this class up into a nullable and non-null components.
+template <typename T>
+class ColumnStorage : public ColumnStorageBase {
+ public:
+ ColumnStorage() = default;
+
+ explicit ColumnStorage(const ColumnStorage&) = delete;
+ ColumnStorage& operator=(const ColumnStorage&) = delete;
+
+ ColumnStorage(ColumnStorage&&) = default;
+ ColumnStorage& operator=(ColumnStorage&&) noexcept = default;
+
+ base::Optional<T> Get(uint32_t idx) const { return nv_.Get(idx); }
+ T GetNonNull(uint32_t non_null_idx) const {
+ return nv_.GetNonNull(non_null_idx);
+ }
+ void Append(T val) { nv_.Append(val); }
+ void Append(base::Optional<T> val) { nv_.Append(val); }
+ void Set(uint32_t idx, T val) { nv_.Set(idx, val); }
+ uint32_t size() const { return nv_.size(); }
+ bool IsDense() const { return nv_.IsDense(); }
+
+ static ColumnStorage<T> Sparse() {
+ return ColumnStorage<T>(NullableVector<T>::Sparse());
+ }
+ static ColumnStorage<T> Dense() {
+ return ColumnStorage<T>(NullableVector<T>::Dense());
+ }
+
+ private:
+ explicit ColumnStorage(NullableVector<T> nv) : nv_(std::move(nv)) {}
+
+ NullableVector<T> nv_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_DB_COLUMN_STORAGE_H_
diff --git a/src/trace_processor/db/typed_column.h b/src/trace_processor/db/typed_column.h
index c5aec10..e34d38d 100644
--- a/src/trace_processor/db/typed_column.h
+++ b/src/trace_processor/db/typed_column.h
@@ -89,13 +89,11 @@
}
// Inserts the value at the end of the column.
- void Append(T v) {
- mutable_nullable_vector()->Append(Serializer::Serialize(v));
- }
+ void Append(T v) { mutable_storage()->Append(Serializer::Serialize(v)); }
// Returns the row containing the given value in the Column.
base::Optional<uint32_t> IndexOf(sql_value_type v) const {
- return Column::IndexOf(ToValue(v));
+ return Column::IndexOf(ToSqlValue(v));
}
std::vector<T> ToVectorForTesting() const {
@@ -106,12 +104,12 @@
}
// Helper functions to create constraints for the given value.
- Constraint eq(sql_value_type v) const { return eq_value(ToValue(v)); }
- Constraint gt(sql_value_type v) const { return gt_value(ToValue(v)); }
- Constraint lt(sql_value_type v) const { return lt_value(ToValue(v)); }
- Constraint ne(sql_value_type v) const { return ne_value(ToValue(v)); }
- Constraint ge(sql_value_type v) const { return ge_value(ToValue(v)); }
- Constraint le(sql_value_type v) const { return le_value(ToValue(v)); }
+ Constraint eq(sql_value_type v) const { return eq_value(ToSqlValue(v)); }
+ Constraint gt(sql_value_type v) const { return gt_value(ToSqlValue(v)); }
+ Constraint lt(sql_value_type v) const { return lt_value(ToSqlValue(v)); }
+ Constraint ne(sql_value_type v) const { return ne_value(ToSqlValue(v)); }
+ Constraint ge(sql_value_type v) const { return ge_value(ToSqlValue(v)); }
+ Constraint le(sql_value_type v) const { return le_value(ToSqlValue(v)); }
// Implements equality between two items of type |T|.
static constexpr bool Equals(T a, T b) { return TH::Equals(a, b); }
@@ -144,18 +142,18 @@
// Public for use by macro tables.
void SetAtIdx(uint32_t idx, non_optional_type v) {
auto serialized = Serializer::Serialize(v);
- mutable_nullable_vector()->Set(idx, serialized);
+ mutable_storage()->Set(idx, serialized);
}
// Public for use by macro tables.
T GetAtIdx(uint32_t idx) const {
- return Serializer::Deserialize(TH::Get(nullable_vector(), idx));
+ return Serializer::Deserialize(TH::Get(storage(), idx));
}
template <bool is_string = TH::is_string>
typename std::enable_if<is_string, NullTermStringView>::type GetStringAtIdx(
uint32_t idx) const {
- return string_pool().Get(nullable_vector().GetNonNull(idx));
+ return string_pool().Get(storage().GetNonNull(idx));
}
private:
@@ -178,18 +176,11 @@
}
}
- static SqlValue ToValue(double value) { return SqlValue::Double(value); }
- static SqlValue ToValue(uint32_t value) { return SqlValue::Long(value); }
- static SqlValue ToValue(int64_t value) { return SqlValue::Long(value); }
- static SqlValue ToValue(NullTermStringView value) {
- return SqlValue::String(value.c_str());
+ const storage_type& storage() const {
+ return Column::storage<serialized_type>();
}
-
- const NullableVector<serialized_type>& nullable_vector() const {
- return Column::nullable_vector<serialized_type>();
- }
- NullableVector<serialized_type>* mutable_nullable_vector() {
- return Column::mutable_nullable_vector<serialized_type>();
+ storage_type* mutable_storage() {
+ return Column::mutable_storage<serialized_type>();
}
};
diff --git a/src/trace_processor/db/typed_column_internal.h b/src/trace_processor/db/typed_column_internal.h
index d3c6061..cc9207b 100644
--- a/src/trace_processor/db/typed_column_internal.h
+++ b/src/trace_processor/db/typed_column_internal.h
@@ -20,6 +20,7 @@
#include "src/trace_processor/containers/nullable_vector.h"
#include "src/trace_processor/containers/string_pool.h"
#include "src/trace_processor/db/base_id.h"
+#include "src/trace_processor/db/column_storage.h"
namespace perfetto {
namespace trace_processor {
@@ -95,7 +96,7 @@
using serialized_type =
typename Serializer<non_optional_type>::serialized_type;
using sql_value_type = serialized_type;
- using storage_type = NullableVector<serialized_type>;
+ using storage_type = ColumnStorage<serialized_type>;
static constexpr bool is_optional = false;
static constexpr bool is_string = false;
@@ -124,7 +125,7 @@
using serialized_type =
typename Serializer<non_optional_type>::serialized_type;
using sql_value_type = serialized_type;
- using storage_type = NullableVector<serialized_type>;
+ using storage_type = ColumnStorage<serialized_type>;
static constexpr bool is_optional = true;
static constexpr bool is_string = false;
@@ -156,7 +157,7 @@
using non_optional_type = StringPool::Id;
using serialized_type = StringPool::Id;
using sql_value_type = NullTermStringView;
- using storage_type = NullableVector<serialized_type>;
+ using storage_type = ColumnStorage<serialized_type>;
static constexpr bool is_optional = false;
static constexpr bool is_string = true;
@@ -181,7 +182,7 @@
using non_optional_type = StringPool::Id;
using serialized_type = StringPool::Id;
using sql_value_type = NullTermStringView;
- using storage_type = NullableVector<serialized_type>;
+ using storage_type = ColumnStorage<serialized_type>;
// is_optional is false again because we always unwrap
// base::Optional<StringPool::Id> into StringPool::Id.
diff --git a/src/trace_processor/dynamic/ancestor_generator.cc b/src/trace_processor/dynamic/ancestor_generator.cc
index e7a3154..722724e 100644
--- a/src/trace_processor/dynamic/ancestor_generator.cc
+++ b/src/trace_processor/dynamic/ancestor_generator.cc
@@ -100,7 +100,7 @@
ConstraintType constraint_value,
const ParentTable& table,
std::vector<typename ParentTable::RowNumber> parent_rows) {
- NullableVector<ConstraintType> start_ids;
+ ColumnStorage<ConstraintType> start_ids;
for (uint32_t i = 0; i < parent_rows.size(); ++i)
start_ids.Append(constraint_value);
return ChildTable::SelectAndExtendParent(table, std::move(parent_rows),
diff --git a/src/trace_processor/dynamic/connected_flow_generator.cc b/src/trace_processor/dynamic/connected_flow_generator.cc
index bb3cf3d..1565a4c 100644
--- a/src/trace_processor/dynamic/connected_flow_generator.cc
+++ b/src/trace_processor/dynamic/connected_flow_generator.cc
@@ -251,7 +251,7 @@
std::move(bfs).TakeResultingFlows();
// Aditional column for start_id
- NullableVector<uint32_t> start_ids;
+ ColumnStorage<uint32_t> start_ids;
for (size_t i = 0; i < result_rows.size(); i++) {
start_ids.Append(start_id.value);
}
diff --git a/src/trace_processor/dynamic/descendant_generator.cc b/src/trace_processor/dynamic/descendant_generator.cc
index a2dd5f5..72d260f 100644
--- a/src/trace_processor/dynamic/descendant_generator.cc
+++ b/src/trace_processor/dynamic/descendant_generator.cc
@@ -53,7 +53,7 @@
ConstraintType constraint_id,
const ParentTable& table,
std::vector<typename ParentTable::RowNumber> parent_rows) {
- NullableVector<ConstraintType> start_ids;
+ ColumnStorage<ConstraintType> start_ids;
for (uint32_t i = 0; i < parent_rows.size(); ++i)
start_ids.Append(constraint_id);
return ChildTable::SelectAndExtendParent(table, std::move(parent_rows),
diff --git a/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc b/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
index 1dfa722..3cee91a 100644
--- a/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
+++ b/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
@@ -258,14 +258,14 @@
// Build the dynamic table.
PERFETTO_DCHECK(cs_rows.size() == annotations_reversed.size());
- NullableVector<StringPool::Id> annotation_vals;
+ ColumnStorage<StringPool::Id> annotation_vals;
for (auto it = annotations_reversed.rbegin();
it != annotations_reversed.rend(); ++it) {
annotation_vals.Append(*it);
}
// Hidden column - always the input, i.e. the callsite leaf.
- NullableVector<uint32_t> start_id_vals;
+ ColumnStorage<uint32_t> start_id_vals;
for (uint32_t i = 0; i < cs_rows.size(); i++)
start_id_vals.Append(start_id.value);
diff --git a/src/trace_processor/dynamic/experimental_counter_dur_generator.cc b/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
index d752d4c..2407e0d 100644
--- a/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
+++ b/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
@@ -69,11 +69,11 @@
}
// static
-NullableVector<int64_t> ExperimentalCounterDurGenerator::ComputeDurColumn(
+ColumnStorage<int64_t> ExperimentalCounterDurGenerator::ComputeDurColumn(
const Table& table) {
// Keep track of the last seen row for each track id.
std::unordered_map<TrackId, uint32_t> last_row_for_track_id;
- NullableVector<int64_t> dur;
+ ColumnStorage<int64_t> dur;
const auto* ts_col =
TypedColumn<int64_t>::FromColumn(table.GetColumnByName("ts"));
@@ -104,11 +104,11 @@
}
// static
-NullableVector<double> ExperimentalCounterDurGenerator::ComputeDeltaColumn(
+ColumnStorage<double> ExperimentalCounterDurGenerator::ComputeDeltaColumn(
const Table& table) {
// Keep track of the last seen row for each track id.
std::unordered_map<TrackId, uint32_t> last_row_for_track_id;
- NullableVector<double> delta;
+ ColumnStorage<double> delta;
const auto* value_col =
TypedColumn<double>::FromColumn(table.GetColumnByName("value"));
diff --git a/src/trace_processor/dynamic/experimental_counter_dur_generator.h b/src/trace_processor/dynamic/experimental_counter_dur_generator.h
index 640cbf1..d513588 100644
--- a/src/trace_processor/dynamic/experimental_counter_dur_generator.h
+++ b/src/trace_processor/dynamic/experimental_counter_dur_generator.h
@@ -38,8 +38,8 @@
std::unique_ptr<Table>& table_return) override;
// public + static for testing
- static NullableVector<int64_t> ComputeDurColumn(const Table& table);
- static NullableVector<double> ComputeDeltaColumn(const Table& table);
+ static ColumnStorage<int64_t> ComputeDurColumn(const Table& table);
+ static ColumnStorage<double> ComputeDeltaColumn(const Table& table);
private:
const tables::CounterTable* counter_table_ = nullptr;
diff --git a/src/trace_processor/dynamic/experimental_sched_upid_generator.cc b/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
index 923e963..c2e0dcf 100644
--- a/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
+++ b/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
@@ -65,8 +65,8 @@
return base::OkStatus();
}
-NullableVector<uint32_t> ExperimentalSchedUpidGenerator::ComputeUpidColumn() {
- NullableVector<uint32_t> upid;
+ColumnStorage<uint32_t> ExperimentalSchedUpidGenerator::ComputeUpidColumn() {
+ ColumnStorage<uint32_t> upid;
for (uint32_t i = 0; i < sched_slice_table_->row_count(); ++i) {
upid.Append(thread_table_->upid()[sched_slice_table_->utid()[i]]);
}
diff --git a/src/trace_processor/dynamic/experimental_sched_upid_generator.h b/src/trace_processor/dynamic/experimental_sched_upid_generator.h
index 9c0f7ae..d0d8538 100644
--- a/src/trace_processor/dynamic/experimental_sched_upid_generator.h
+++ b/src/trace_processor/dynamic/experimental_sched_upid_generator.h
@@ -41,7 +41,7 @@
std::unique_ptr<Table>& table_return) override;
private:
- NullableVector<uint32_t> ComputeUpidColumn();
+ ColumnStorage<uint32_t> ComputeUpidColumn();
const tables::SchedSliceTable* sched_slice_table_;
const tables::ThreadTable* thread_table_;
diff --git a/src/trace_processor/dynamic/experimental_slice_layout_generator.cc b/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
index 63fcd8f..ded6fe4 100644
--- a/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
+++ b/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
@@ -265,8 +265,8 @@
}
// Step 3: Add the two new columns layout_depth and filter_track_ids:
- NullableVector<uint32_t> layout_depth_column;
- NullableVector<StringPool::Id> filter_column;
+ ColumnStorage<uint32_t> layout_depth_column;
+ ColumnStorage<StringPool::Id> filter_column;
for (tables::SliceTable::RowNumber i : rows) {
auto ref = i.ToRowReference(*slice_table_);
diff --git a/src/trace_processor/tables/macros_internal.h b/src/trace_processor/tables/macros_internal.h
index b1a4020..320329b 100644
--- a/src/trace_processor/tables/macros_internal.h
+++ b/src/trace_processor/tables/macros_internal.h
@@ -93,7 +93,7 @@
row_maps_.emplace_back();
columns_.emplace_back(Column::IdColumn(this, 0, 0));
columns_.emplace_back(
- Column("type", &type_, Column::kNoFlag, this, 1, 0));
+ Column("type", &type_, Column::kNonNull, this, 1, 0));
return;
}