GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
889 / 1192
74.6%
Branches:
450 / 939
47.9%
Functions:
198 / 249, 9 excl
79.5%

scene/storage.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file storage.h
3 /// @brief Columnar prim storage: prims in buckets by type and applied API schemas, each attribute
4 /// one array per bucket, with versions per bucket, column and 64-row chunk for change tracking.
5 #pragma once
6
7 #include "ernie/scene/path.h"
8 #include "ernie/util/bytes.h"
9 #include "ernie/util/glm.h"
10 #include "ernie/util/tensor.h"
11
12 #include <glm/gtc/quaternion.hpp>
13
14 #include <algorithm>
15 #include <array>
16 #include <cstdint>
17 #include <deque>
18 #include <limits>
19 #include <memory>
20 #include <optional>
21 #include <span>
22 #include <stdexcept>
23 #include <tuple>
24 #include <type_traits>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28
29 namespace ernie {
30
31 /// @brief A prim's handle: its slot, and the slot's generation when the prim was defined, so a
32 /// handle to a removed prim is detected rather than reaching its slot's next prim.
33
1/4
✓ Branch 1 taken 1620 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
77583 struct PrimId {
34 5068 std::uint32_t slot = std::numeric_limits<std::uint32_t>::max();
35 5068 std::uint32_t generation = 0;
36
37
10/16
<unknown function 33>:
✓ Branch 0 taken 52 times.
✓ Branch 0 taken 4948 times.
✗ Branch 1 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✓ Branch 2 taken 4947 times.
✗ Branch 3 not taken.
✓ Branch 3 taken 1 time.
<unknown function 34>:
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 59 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 59 times.
✗ Branch 7 not taken.
5068 bool operator==(const PrimId&) const = default;
38 };
39
40 using AttributeId = Token;
41 using BucketId = std::uint32_t;
42
43 /// @brief The element types columns hold. Bools are bytes, so a column is always a contiguous
44 /// array; tokens and path ids are the scene's interned names and paths.
45 enum class ColumnType : std::uint8_t {
46 Bool,
47 Int,
48 Double,
49 Vec2,
50 Vec3,
51 Vec4,
52 Quat,
53 Matrix,
54 TokenValue,
55 Relationship,
56 Relationships,
57 FloatArray,
58 TokenArray,
59 Tensor,
60 };
61
62 /// A relationship's single target, distinct from a token though both are 32-bit ids.
63 struct Target {
64 683 PathId path = kNoPath;
65
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 676 times.
683 bool operator==(const Target&) const = default;
66 };
67
68 /// The element type of each column type, in `ColumnType`'s order.
69 using ColumnElements =
70 std::tuple<std::uint8_t, std::int32_t, double, glm::dvec2, glm::dvec3, glm::dvec4, glm::dquat,
71 glm::dmat4, Token, Target, std::vector<Target>, std::vector<float>,
72 std::vector<Token>, Tensor>;
73 static_assert(std::tuple_size_v<ColumnElements> ==
74 static_cast<std::size_t>(ColumnType::Tensor) + 1);
75
76 /// The column type of element type `T`.
77 template <typename T>
78 inline constexpr ColumnType kColumnType =
79 []<typename... Ts>(std::type_identity<std::tuple<Ts...>>) {
80 constexpr std::array matches{std::is_same_v<T, Ts>...};
81 constexpr auto index =
82 static_cast<std::size_t>(std::ranges::find(matches, true) - matches.begin());
83 static_assert(index < matches.size(), "Not a column element type");
84 return static_cast<ColumnType>(index);
85 }(std::type_identity<ColumnElements>{});
86
87 /// @brief Calls `visit(std::type_identity<T>{})` with the element type `T` of a column type.
88 template <std::size_t I = 0, typename Visit>
89 214369 decltype(auto) WithColumnType(ColumnType type, Visit&& visit) {
90 if constexpr (I + 1 < std::tuple_size_v<ColumnElements>) {
91
96/120
decltype(auto) ernie::WithColumnType<0ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<0ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7923 times.
✓ Branch 1 taken 509 times.
decltype(auto) ernie::WithColumnType<0ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4874 times.
✓ Branch 1 taken 14 times.
decltype(auto) ernie::WithColumnType<0ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 12224 times.
✓ Branch 1 taken 13 times.
decltype(auto) ernie::WithColumnType<0ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 248 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<10ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1314 times.
✓ Branch 1 taken 279 times.
decltype(auto) ernie::WithColumnType<10ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1621 times.
✓ Branch 1 taken 22 times.
decltype(auto) ernie::WithColumnType<10ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 6994 times.
✓ Branch 1 taken 15 times.
decltype(auto) ernie::WithColumnType<10ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<11ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1018 times.
✓ Branch 1 taken 296 times.
decltype(auto) ernie::WithColumnType<11ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 21 times.
decltype(auto) ernie::WithColumnType<11ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 6977 times.
✓ Branch 1 taken 17 times.
decltype(auto) ernie::WithColumnType<11ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<12ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 572 times.
✓ Branch 1 taken 446 times.
decltype(auto) ernie::WithColumnType<12ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✓ Branch 1 taken 1600 times.
decltype(auto) ernie::WithColumnType<12ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6961 times.
decltype(auto) ernie::WithColumnType<12ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<1ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<1ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 6882 times.
✓ Branch 1 taken 1041 times.
decltype(auto) ernie::WithColumnType<1ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4845 times.
✓ Branch 1 taken 29 times.
decltype(auto) ernie::WithColumnType<1ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 12194 times.
✓ Branch 1 taken 30 times.
decltype(auto) ernie::WithColumnType<1ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 62 times.
decltype(auto) ernie::WithColumnType<2ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
decltype(auto) ernie::WithColumnType<2ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 5180 times.
✓ Branch 1 taken 1702 times.
decltype(auto) ernie::WithColumnType<2ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 3606 times.
✓ Branch 1 taken 1239 times.
decltype(auto) ernie::WithColumnType<2ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 11962 times.
✓ Branch 1 taken 232 times.
decltype(auto) ernie::WithColumnType<2ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<3ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<3ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 5117 times.
✓ Branch 1 taken 63 times.
decltype(auto) ernie::WithColumnType<3ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 3579 times.
✓ Branch 1 taken 27 times.
decltype(auto) ernie::WithColumnType<3ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 11939 times.
✓ Branch 1 taken 23 times.
decltype(auto) ernie::WithColumnType<3ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<4ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 7 times.
decltype(auto) ernie::WithColumnType<4ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4838 times.
✓ Branch 1 taken 279 times.
decltype(auto) ernie::WithColumnType<4ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1908 times.
✓ Branch 1 taken 1671 times.
decltype(auto) ernie::WithColumnType<4ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7197 times.
✓ Branch 1 taken 4742 times.
decltype(auto) ernie::WithColumnType<4ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<5ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<5ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4822 times.
✓ Branch 1 taken 16 times.
decltype(auto) ernie::WithColumnType<5ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1907 times.
✓ Branch 1 taken 1 time.
decltype(auto) ernie::WithColumnType<5ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7196 times.
✓ Branch 1 taken 1 time.
decltype(auto) ernie::WithColumnType<5ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<6ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
decltype(auto) ernie::WithColumnType<6ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4822 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<6ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1828 times.
✓ Branch 1 taken 79 times.
decltype(auto) ernie::WithColumnType<6ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7155 times.
✓ Branch 1 taken 41 times.
decltype(auto) ernie::WithColumnType<6ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<7ul, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::ConvertRows(ernie::ColumnValues const&, unsigned int, unsigned int, std::span<std::byte, 18446744073709551615ul>)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<7ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 4822 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<7ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1812 times.
✓ Branch 1 taken 16 times.
decltype(auto) ernie::WithColumnType<7ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7133 times.
✓ Branch 1 taken 22 times.
decltype(auto) ernie::WithColumnType<7ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
decltype(auto) ernie::WithColumnType<8ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 2074 times.
✓ Branch 1 taken 2748 times.
decltype(auto) ernie::WithColumnType<8ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1675 times.
✓ Branch 1 taken 137 times.
decltype(auto) ernie::WithColumnType<8ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7030 times.
✓ Branch 1 taken 103 times.
decltype(auto) ernie::WithColumnType<8ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 124 times.
decltype(auto) ernie::WithColumnType<9ul, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::(anonymous namespace)::MakeLayout(ernie::PathTable&, ernie::AttributeDef const&, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 481 times.
decltype(auto) ernie::WithColumnType<9ul, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Author(ernie::PrimId, std::basic_string_view<char, std::char_traits<char> >, ernie::Value const&, ernie::Value*)::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 1643 times.
✓ Branch 1 taken 32 times.
decltype(auto) ernie::WithColumnType<9ul, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::CellValue(ernie::PrimId, ernie::Column const*) const::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✓ Branch 0 taken 7009 times.
✓ Branch 1 taken 21 times.
decltype(auto) ernie::WithColumnType<9ul, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}>(ernie::ColumnType, ernie::Scene::Resolve()::{lambda<typename $T0>(std::type_identity<$T0>)#1}&&):
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
213781 if (static_cast<std::size_t>(type) != I) {
92 188553 return WithColumnType<I + 1>(type, std::forward<Visit>(visit));
93 }
94 }
95 25816 return visit(std::type_identity<std::tuple_element_t<I, ColumnElements>>{});
96 }
97
98 /// Rows a version chunk covers: one word of the authored bits.
99 inline constexpr std::uint32_t kChunkRows = BitSet::kWordBits;
100
101 /// @brief A column's values, their element type erased.
102 17092 class ColumnValues {
103 public:
104 6857 virtual ~ColumnValues() = default;
105 virtual ColumnType Type() const = 0;
106 /// @return An empty column of the same type and fallback.
107 virtual std::unique_ptr<ColumnValues> Clone() const = 0;
108 /// Appends `count` rows holding the fallback.
109 virtual void Grow(std::size_t count) = 0;
110 /// Moves the last row into `row` and drops the last.
111 virtual void SwapRemove(std::size_t row) = 0;
112 /// Puts the fallback back in `row`.
113 virtual void Reset(std::size_t row) = 0;
114 /// Copies `source`'s value at `from` into `row`; `source` holds the same type.
115 virtual void CopyRow(std::size_t row, const ColumnValues& source, std::size_t from) = 0;
116 };
117
118 6857 template <typename T> class TypedColumn final : public ColumnValues {
119 public:
120 9744 explicit TypedColumn(T fallback) : fallback_(std::move(fallback)) {}
121
122 78410 ColumnType Type() const override {
123 78410 return kColumnType<T>;
124 }
125 8450 std::unique_ptr<ColumnValues> Clone() const override {
126
12/28
ernie::TypedColumn<double>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 1712 times.
ernie::TypedColumn<ernie::Target>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 481 times.
ernie::TypedColumn<ernie::Tensor>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 572 times.
ernie::TypedColumn<glm::mat<4, 4, double, (glm::qualifier)0> >::Clone() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
ernie::TypedColumn<glm::qua<double, (glm::qualifier)0> >::Clone() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
ernie::TypedColumn<glm::vec<2, double, (glm::qualifier)0> >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
ernie::TypedColumn<glm::vec<3, double, (glm::qualifier)0> >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 287 times.
ernie::TypedColumn<glm::vec<4, double, (glm::qualifier)0> >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
ernie::TypedColumn<int>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 1041 times.
ernie::TypedColumn<std::vector<ernie::Target, std::allocator<ernie::Target> > >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 279 times.
ernie::TypedColumn<std::vector<float, std::allocator<float> > >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 296 times.
ernie::TypedColumn<std::vector<unsigned int, std::allocator<unsigned int> > >::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 446 times.
ernie::TypedColumn<unsigned char>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 509 times.
ernie::TypedColumn<unsigned int>::Clone() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 2748 times.
8450 return std::make_unique<TypedColumn<T>>(fallback_);
127 }
128 189053 void Grow(std::size_t count) override {
129 189053 values_.resize(values_.size() + count, fallback_);
130 189053 }
131 144854 void SwapRemove(std::size_t row) override {
132
19/28
ernie::TypedColumn<double>::SwapRemove(unsigned long):
✓ Branch 0 taken 487 times.
✓ Branch 1 taken 70333 times.
ernie::TypedColumn<ernie::Target>::SwapRemove(unsigned long):
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 99 times.
ernie::TypedColumn<ernie::Tensor>::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
ernie::TypedColumn<glm::mat<4, 4, double, (glm::qualifier)0> >::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
ernie::TypedColumn<glm::qua<double, (glm::qualifier)0> >::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
ernie::TypedColumn<glm::vec<2, double, (glm::qualifier)0> >::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
ernie::TypedColumn<glm::vec<3, double, (glm::qualifier)0> >::SwapRemove(unsigned long):
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 70035 times.
ernie::TypedColumn<glm::vec<4, double, (glm::qualifier)0> >::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
ernie::TypedColumn<int>::SwapRemove(unsigned long):
✓ Branch 0 taken 492 times.
✓ Branch 1 taken 193 times.
ernie::TypedColumn<std::vector<ernie::Target, std::allocator<ernie::Target> > >::SwapRemove(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
ernie::TypedColumn<std::vector<float, std::allocator<float> > >::SwapRemove(unsigned long):
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 42 times.
ernie::TypedColumn<std::vector<unsigned int, std::allocator<unsigned int> > >::SwapRemove(unsigned long):
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 80 times.
ernie::TypedColumn<unsigned char>::SwapRemove(unsigned long):
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 62 times.
ernie::TypedColumn<unsigned int>::SwapRemove(unsigned long):
✓ Branch 0 taken 1225 times.
✓ Branch 1 taken 467 times.
144854 if (row + 1 != values_.size()) {
133 3431 values_[row] = std::move(values_.back());
134 }
135 144854 values_.pop_back();
136 144854 }
137 10 void Reset(std::size_t row) override {
138 10 values_[row] = fallback_;
139 10 }
140 11 void CopyRow(std::size_t row, const ColumnValues& source, std::size_t from) override {
141 11 values_[row] = static_cast<const TypedColumn&>(source).values_[from];
142 11 }
143
144 std::vector<T>& Values() {
145 return values_;
146 }
147 54769 const std::vector<T>& Values() const {
148 54780 return values_;
149 }
150
151 private:
152 std::vector<T> values_;
153 T fallback_;
154 };
155
156 /// @brief One column of a bucket's layout: an attribute and how to make its values.
157
7/28
<unknown function 34>:
✓ Branch 0 taken 6550 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
<unknown function 89>:
✗ Branch 0 not taken.
✓ Branch 1 taken 10828 times.
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1736 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 6696 times.
✓ Branch 12 taken 6696 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
ernie::TypedColumn<glm::mat<4, 4, double, (glm::qualifier)0> >::CopyRow(unsigned long, ernie::ColumnValues const&, unsigned long):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
44596 struct ColumnLayout {
158 AttributeId attribute = 0;
159 std::shared_ptr<const ColumnValues> prototype;
160
161 /// @return A column of `T` whose unauthored rows hold `fallback`.
162 8450 template <typename T> static ColumnLayout Make(AttributeId attribute, T fallback = {}) {
163 8450 return {attribute, std::make_shared<TypedColumn<T>>(std::move(fallback))};
164
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8450 }
165 };
166
167 /// @brief What a bucket groups: a prim type and its applied API schemas, kept sorted.
168
6/10
<unknown function 33>:
✓ Branch 3 taken 726 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 2324 times.
✓ Branch 9 taken 715 times.
<unknown function 34>:
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
12030 struct BucketKey {
169 2326 Token type = 0;
170 2326 std::vector<Token> apiSchemas;
171
172 /// @return The key with its API schemas sorted and without repeats.
173 BucketKey Normalized() const;
174
2/4
✓ Branch 0 taken 2326 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2326 times.
2326 bool operator==(const BucketKey&) const = default;
175 };
176
177 /// @brief A change to a bucket's rows.
178 struct StructuralChange {
179 enum class Kind : std::uint8_t {
180 /// `count` rows added from `row`.
181 Added,
182 /// The prim at `row` removed.
183 Removed,
184 /// The prim at `from` moved to `row` (the last row, into a removed one's place).
185 Moved,
186 /// The bucket's `count` rows, all new to a reader too far behind to replay its log.
187 Reset,
188 };
189 std::uint64_t version = 0;
190 Kind kind = Kind::Added;
191 std::uint32_t row = 0;
192 std::uint32_t count = 1;
193 std::uint32_t from = 0;
194 };
195
196 /// @brief One attribute of every prim of a bucket, with its authored rows and versions.
197 struct Column {
198 AttributeId attribute = 0;
199 std::unique_ptr<ColumnValues> values;
200 BitSet authored;
201 /// The last version that changed any of chunk c's rows.
202 std::vector<std::uint64_t> chunkVersions;
203 std::uint64_t version = 0;
204
205 /// Sizes the authored bits and chunk versions for `rows` rows.
206 333907 void Resize(std::uint32_t rows) {
207 333907 authored.Resize(rows);
208 333907 chunkVersions.resize(BitSet::WordCount(rows), 0);
209 333907 }
210 };
211
212 /// @brief Prims of one key, a row each, in structure-of-arrays columns.
213 struct Bucket {
214 BucketKey key;
215 /// The prim of each row.
216 std::vector<PrimId> prims;
217 std::vector<Column> columns;
218 std::unordered_map<AttributeId, std::uint32_t> columnIndex;
219 /// The last version that changed the bucket's rows or values.
220 std::uint64_t version = 0;
221 /// Row changes newer than `logStart`; older ones are dropped.
222 std::deque<StructuralChange> log;
223 std::uint64_t logStart = 0;
224
225 204416 std::uint32_t Rows() const {
226
11/18
<unknown function 33>:
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4084 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
<unknown function 34>:
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
<unknown function 64>:
✓ Branch 0 taken 356 times.
✓ Branch 1 taken 32476 times.
<unknown function 89>:
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
ernie::Column::Resize(unsigned int):
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1012 times.
✓ Branch 4 taken 5656 times.
✓ Branch 8 taken 8642 times.
✗ Branch 9 not taken.
204416 return static_cast<std::uint32_t>(prims.size());
227 }
228 /// @return The attribute's column, or null if the bucket has none.
229 129181 const Column* Find(AttributeId attribute) const {
230 129181 const auto found = columnIndex.find(attribute);
231
2/2
✓ Branch 0 taken 127910 times.
✓ Branch 1 taken 1271 times.
129181 return found == columnIndex.end() ? nullptr : &columns[found->second];
232 }
233 84536 Column* Find(AttributeId attribute) {
234 84536 return const_cast<Column*>(std::as_const(*this).Find(attribute));
235 }
236 };
237
238 /// @brief Rows [begin, end) of a column, changed.
239 struct RowRange {
240 2 std::uint32_t begin = 0;
241 2 std::uint32_t end = 0;
242
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 bool operator==(const RowRange&) const = default;
243 };
244
245 /// @brief What changed since a cursor (`PrimStore::ChangesSince`).
246
7/14
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 time.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 time.
✓ Branch 23 taken 1 time.
✗ Branch 24 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
✓ Branch 33 taken 1 time.
✗ Branch 34 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 time.
301 struct ChangeSet {
247 /// The cursor to pass next time.
248 std::uint64_t version = 0;
249 struct Rows {
250 BucketId bucket = 0;
251 StructuralChange change;
252 };
253 8906 struct Values {
254 BucketId bucket = 0;
255 AttributeId attribute = 0;
256 std::vector<RowRange> rows;
257 };
258 /// Row changes in order.
259 std::vector<Rows> rows;
260 /// Changed values, by column.
261 std::vector<Values> values;
262 };
263
264 /// @brief The scene's prims in columns.
265 /// One writer at a time; readers between writes. Every write stamps a new version; a reader's
266 /// cursor is the version it last saw, and `ChangesSince` returns what changed after it without
267 /// scanning unchanged buckets, columns or chunks.
268 class PrimStore {
269 public:
270 242 PrimStore() = default;
271 PrimStore(const PrimStore&) = delete;
272 PrimStore& operator=(const PrimStore&) = delete;
273 PrimStore(PrimStore&&) = default;
274 PrimStore& operator=(PrimStore&&) = default;
275
276 39658 PathTable& Paths() {
277
21/87
ernie::Bucket::Find(unsigned int) const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 9151 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 25 taken 18308 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 697 times.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✓ Branch 41 taken 62 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 56 taken 124 times.
✗ Branch 57 not taken.
✓ Branch 59 taken 62 times.
✗ Branch 60 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
ernie::PrimStore::PrimStore():
✓ Branch 0 taken 2794 times.
✓ Branch 1 taken 246 times.
✗ Branch 2 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
✓ Branch 5 taken 29 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 1 time.
✓ Branch 8 taken 1237 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✓ Branch 11 taken 27 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✓ Branch 14 taken 1671 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 time.
✗ Branch 19 not taken.
✓ Branch 20 taken 79 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 16 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
67252 return paths_;
278 }
279 21640 const PathTable& Paths() const {
280
6/8
<unknown function 33>:
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
ernie::Bucket::Find(unsigned int) const:
✓ Branch 1 taken 248 times.
✗ Branch 2 not taken.
ernie::PrimStore::PrimStore():
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 6 times.
✓ Branch 10 taken 32 times.
✓ Branch 11 taken 25 times.
16519 return paths_;
281 }
282 6345 TokenTable& Tokens() {
283
14/27
<unknown function 168>:
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
ernie::Bucket::Find(unsigned int) const:
✓ Branch 1 taken 248 times.
✗ Branch 2 not taken.
ernie::PrimStore::PrimStore():
✓ Branch 1 taken 1 time.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 time.
✓ Branch 7 taken 104 times.
✗ Branch 8 not taken.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 time.
✓ Branch 11 taken 233 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✓ Branch 14 taken 233 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 time.
✓ Branch 17 taken 233 times.
✗ Branch 18 not taken.
5877 return paths_.Names();
284 }
285 21962 const TokenTable& Tokens() const {
286
1/2
✓ Branch 1 taken 3358 times.
✗ Branch 2 not taken.
21962 return paths_.Names();
287 }
288
289 /// @return The bucket of `key`, made with `layout`'s columns if new.
290 BucketId AddBucket(const BucketKey& key, std::span<const ColumnLayout> layout);
291 std::optional<BucketId> FindBucket(const BucketKey& key) const;
292 63104 const Bucket& GetBucket(BucketId bucket) const {
293
7/10
<unknown function 246>:
✓ Branch 0 taken 13434 times.
✓ Branch 1 taken 151 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 2 times.
<unknown function 33>:
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
ernie::Bucket::Find(unsigned int) const:
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
62795 return *buckets_[bucket];
294 }
295 77 std::size_t BucketCount() const {
296
1/2
✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
77 return buckets_.size();
297 }
298
299 /// @brief Defines a prim at `path` in `bucket`, its attributes at their fallbacks.
300 /// @return The prim; the existing one if `path` already has one in `bucket`.
301 /// @throws std::invalid_argument If `path` has a prim in another bucket.
302 PrimId Define(PathId path, BucketId bucket);
303 /// @brief Defines prims at `paths` in `bucket` as one write: one row change, one version.
304 std::vector<PrimId> DefineMany(std::span<const PathId> paths, BucketId bucket);
305 /// @brief Removes a prim; the bucket's last row moves into its place.
306 void Remove(PrimId prim);
307 /// @brief Moves a prim to another bucket, keeping its id and the authored values of the
308 /// attributes both buckets have.
309 void Move(PrimId prim, BucketId bucket);
310
311 bool Alive(PrimId prim) const;
312 std::optional<PrimId> Find(PathId path) const;
313 69078 PathId PrimPath(PrimId prim) const {
314
4/6
<unknown function 33>:
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1510 times.
✗ Branch 5 not taken.
ernie::PrimStore::PrimStore():
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 6 times.
69078 return Slot(prim).path;
315 }
316
2/4
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
102383 BucketId PrimBucket(PrimId prim) const {
317
20/56
<unknown function 168>:
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
ernie::Bucket::Find(unsigned int) const:
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 9153 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 time.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 time.
✗ Branch 21 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 time.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 30 not taken.
✓ Branch 32 taken 1 time.
✗ Branch 33 not taken.
✓ Branch 33 taken 18314 times.
✗ Branch 34 not taken.
✓ Branch 37 taken 697 times.
✗ Branch 38 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
ernie::PrimStore::PrimStore():
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 time.
✓ Branch 10 taken 247 times.
✗ Branch 11 not taken.
✗ Branch 11 not taken.
102387 return Slot(prim).bucket;
318 }
319 48868 std::uint32_t PrimRow(PrimId prim) const {
320
21/35
<unknown function 168>:
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 5 taken 64 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 64 times.
✗ Branch 9 not taken.
<unknown function 33>:
✓ Branch 1 taken 3941 times.
✓ Branch 2 taken 1571 times.
ernie::PrimStore::PrimStore():
✓ Branch 1 taken 1744 times.
✓ Branch 2 taken 12234 times.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 3359 times.
✗ Branch 7 not taken.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 485 times.
✓ Branch 9 taken 2874 times.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 time.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 time.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 time.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 time.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 time.
48868 return Slot(prim).row;
321 }
322 1 std::size_t PrimCount() const {
323
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 return slots_.size() - free_.size();
324 }
325
326 /// @brief Authors an attribute of a prim, adding a column of `T` to its bucket if it has none.
327 4983 template <typename T> void Set(PrimId prim, AttributeId attribute, T value) {
328 4983 const SlotData& slot = Slot(prim);
329 4983 Column& column = FindOrAddColumn<T>(slot.bucket, attribute);
330 4982 Values<T>(column)[slot.row] = std::move(value);
331 4982 Stamp(slot.bucket, column, slot.row, slot.row + 1, Next());
332 4982 }
333 /// @return The authored value, or null if unauthored or of another type.
334 28767 template <typename T> const T* Get(PrimId prim, AttributeId attribute) const {
335 28767 const SlotData& slot = Slot(prim);
336 28767 const Column* column = buckets_[slot.bucket]->Find(attribute);
337
27/84
double const* ernie::PrimStore::Get<double>(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
ernie::Target const* ernie::PrimStore::Get<ernie::Target>(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
ernie::Tensor const* ernie::PrimStore::Get<ernie::Tensor>(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 263 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 175 times.
✓ Branch 5 taken 79 times.
glm::mat<4, 4, double, (glm::qualifier)0> const* ernie::PrimStore::Get<glm::mat<4, 4, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
glm::qua<double, (glm::qualifier)0> const* ernie::PrimStore::Get<glm::qua<double, (glm::qualifier)0> >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
glm::vec<2, double, (glm::qualifier)0> const* ernie::PrimStore::Get<glm::vec<2, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
glm::vec<3, double, (glm::qualifier)0> const* ernie::PrimStore::Get<glm::vec<3, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
glm::vec<4, double, (glm::qualifier)0> const* ernie::PrimStore::Get<glm::vec<4, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
int const* ernie::PrimStore::Get<int>(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 9209 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 9137 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 72 times.
std::vector<ernie::Target, std::allocator<ernie::Target> > const* ernie::PrimStore::Get<std::vector<ernie::Target, std::allocator<ernie::Target> > >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
std::vector<float, std::allocator<float> > const* ernie::PrimStore::Get<std::vector<float, std::allocator<float> > >(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
std::vector<unsigned int, std::allocator<unsigned int> > const* ernie::PrimStore::Get<std::vector<unsigned int, std::allocator<unsigned int> > >(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
unsigned char const* ernie::PrimStore::Get<unsigned char>(ernie::PrimId, unsigned int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
unsigned int const* ernie::PrimStore::Get<unsigned int>(ernie::PrimId, unsigned int) const:
✓ Branch 0 taken 18530 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 18520 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
29110 if (column == nullptr || !column->authored.Test(slot.row) ||
338 343 column->values->Type() != kColumnType<T>) {
339 28599 return nullptr;
340 }
341 168 return &Values<T>(*column)[slot.row];
342 }
343 /// @brief Writes a value derived from others into a column the bucket has, leaving it
344 /// unauthored and touching the row only when the value changes.
345 /// @return Whether it changed; false too when the bucket has no such column.
346 28164 template <typename T> bool Derive(PrimId prim, AttributeId attribute, const T& value) {
347 28164 const SlotData& slot = Slot(prim);
348 28164 Column* column = buckets_[slot.bucket]->Find(attribute);
349
12/52
bool ernie::PrimStore::Derive<double>(ernie::PrimId, unsigned int, double const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<ernie::Target>(ernie::PrimId, unsigned int, ernie::Target const&):
✓ Branch 0 taken 683 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 676 times.
bool ernie::PrimStore::Derive<glm::mat<4, 4, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int, glm::mat<4, 4, double, (glm::qualifier)0> const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
bool ernie::PrimStore::Derive<glm::qua<double, (glm::qualifier)0> >(ernie::PrimId, unsigned int, glm::qua<double, (glm::qualifier)0> const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<glm::vec<2, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int, glm::vec<2, double, (glm::qualifier)0> const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<glm::vec<3, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int, glm::vec<3, double, (glm::qualifier)0> const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<glm::vec<4, double, (glm::qualifier)0> >(ernie::PrimId, unsigned int, glm::vec<4, double, (glm::qualifier)0> const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
bool ernie::PrimStore::Derive<int>(ernie::PrimId, unsigned int, int const&):
✓ Branch 0 taken 9139 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 9029 times.
✓ Branch 3 taken 110 times.
bool ernie::PrimStore::Derive<std::vector<ernie::Target, std::allocator<ernie::Target> > >(ernie::PrimId, unsigned int, std::vector<ernie::Target, std::allocator<ernie::Target> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
bool ernie::PrimStore::Derive<std::vector<float, std::allocator<float> > >(ernie::PrimId, unsigned int, std::vector<float, std::allocator<float> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
bool ernie::PrimStore::Derive<std::vector<unsigned int, std::allocator<unsigned int> > >(ernie::PrimId, unsigned int, std::vector<unsigned int, std::allocator<unsigned int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<unsigned char>(ernie::PrimId, unsigned int, unsigned char const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
bool ernie::PrimStore::Derive<unsigned int>(ernie::PrimId, unsigned int, unsigned int const&):
✓ Branch 0 taken 18286 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 18276 times.
✓ Branch 3 taken 10 times.
56272 if (column == nullptr || Values<T>(*column)[slot.row] == value) {
350 28037 return false;
351 }
352 127 Values<T>(*column)[slot.row] = value;
353 127 Touch(slot.bucket, *column, slot.row, slot.row + 1, Next());
354 127 return true;
355 }
356 /// @brief Unauthors an attribute, putting its fallback back.
357 void Clear(PrimId prim, AttributeId attribute);
358
359 /// @brief Writes a whole column at once: every row authored, one change of all rows.
360 /// @return The values to fill, valid until the next structural change.
361 1 template <typename T> std::span<T> Write(BucketId bucket, AttributeId attribute) {
362 1 Column& column = FindOrAddColumn<T>(bucket, attribute);
363 1 const std::uint32_t rows = buckets_[bucket]->Rows();
364 2 Stamp(bucket, column, 0, rows, Next());
365 1 return Values<T>(column);
366 }
367 /// @return A column's values, fallbacks where unauthored; empty if the bucket has none.
368 21383 template <typename T> std::span<const T> Read(BucketId bucket, AttributeId attribute) const {
369 21383 const Column* column = buckets_[bucket]->Find(attribute);
370
14/28
std::span<double const, 18446744073709551615ul> ernie::PrimStore::Read<double>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 503 times.
std::span<ernie::Target const, 18446744073709551615ul> ernie::PrimStore::Read<ernie::Target>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 8744 times.
std::span<ernie::Tensor const, 18446744073709551615ul> ernie::PrimStore::Read<ernie::Tensor>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
std::span<glm::mat<4, 4, double, (glm::qualifier)0> const, 18446744073709551615ul> ernie::PrimStore::Read<glm::mat<4, 4, double, (glm::qualifier)0> >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
std::span<glm::qua<double, (glm::qualifier)0> const, 18446744073709551615ul> ernie::PrimStore::Read<glm::qua<double, (glm::qualifier)0> >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
std::span<glm::vec<2, double, (glm::qualifier)0> const, 18446744073709551615ul> ernie::PrimStore::Read<glm::vec<2, double, (glm::qualifier)0> >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
std::span<glm::vec<3, double, (glm::qualifier)0> const, 18446744073709551615ul> ernie::PrimStore::Read<glm::vec<3, double, (glm::qualifier)0> >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 4744 times.
std::span<glm::vec<4, double, (glm::qualifier)0> const, 18446744073709551615ul> ernie::PrimStore::Read<glm::vec<4, double, (glm::qualifier)0> >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
std::span<int const, 18446744073709551615ul> ernie::PrimStore::Read<int>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
std::span<std::vector<ernie::Target, std::allocator<ernie::Target> > const, 18446744073709551615ul> ernie::PrimStore::Read<std::vector<ernie::Target, std::allocator<ernie::Target> > >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
std::span<std::vector<float, std::allocator<float> > const, 18446744073709551615ul> ernie::PrimStore::Read<std::vector<float, std::allocator<float> > >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
std::span<std::vector<unsigned int, std::allocator<unsigned int> > const, 18446744073709551615ul> ernie::PrimStore::Read<std::vector<unsigned int, std::allocator<unsigned int> > >(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 6962 times.
std::span<unsigned char const, 18446744073709551615ul> ernie::PrimStore::Read<unsigned char>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
std::span<unsigned int const, 18446744073709551615ul> ernie::PrimStore::Read<unsigned int>(unsigned int, unsigned int) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
21383 return column == nullptr ? std::span<const T>() : std::span<const T>(Values<T>(*column));
371 }
372
373 124 std::uint64_t Version() const {
374
11/22
<unknown function 168>:
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
<unknown function 373>:
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 13 times.
ernie::Bucket::Find(unsigned int) const:
✗ Branch 1 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✗ Branch 5 not taken.
std::span<glm::vec<3, double, (glm::qualifier)0>, 18446744073709551615ul> ernie::PrimStore::Write<glm::vec<3, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 8 not taken.
123 return version_;
375 }
376 /// @return What changed after `cursor`; its `version` is the next cursor.
377 ChangeSet ChangesSince(std::uint64_t cursor) const;
378
379 private:
380 2951 struct SlotData {
381 std::uint32_t generation = 0;
382 BucketId bucket = 0;
383 std::uint32_t row = 0;
384 PathId path = kNoPath;
385 bool alive = false;
386 };
387 struct KeyHash {
388 std::size_t operator()(const BucketKey& key) const;
389 };
390
391 148611 std::uint64_t Next() {
392 148611 return ++version_;
393 }
394 const SlotData& Slot(PrimId prim) const;
395 103500 SlotData& Slot(PrimId prim) {
396 103500 return const_cast<SlotData&>(std::as_const(*this).Slot(prim));
397 }
398 PrimId AddSlot(PathId path, BucketId bucket, std::uint32_t row);
399 /// Appends `count` rows at their fallbacks to a bucket, logged as one change.
400 std::uint32_t AddRows(BucketId bucket, std::uint32_t count);
401 /// Drops a prim's row from its bucket, the last row moving into its place.
402 void DropRow(const SlotData& slot);
403 void Log(Bucket& bucket, StructuralChange change);
404 /// Marks rows [begin, end) authored and changed at `version`.
405 void Stamp(BucketId bucket, Column& column, std::uint32_t begin, std::uint32_t end,
406 std::uint64_t version);
407 /// Marks rows [begin, end) changed at `version`.
408 void Touch(BucketId bucket, Column& column, std::uint32_t begin, std::uint32_t end,
409 std::uint64_t version);
410 Column& AddColumn(Bucket& bucket, AttributeId attribute, std::unique_ptr<ColumnValues> values);
411
412 4984 template <typename T> Column& FindOrAddColumn(BucketId bucket, AttributeId attribute) {
413 4984 Bucket& b = *buckets_[bucket];
414 4984 Column* found = b.Find(attribute);
415
23/28
ernie::Column& ernie::PrimStore::FindOrAddColumn<double>(unsigned int, unsigned int):
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1213 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<ernie::Target>(unsigned int, unsigned int):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 29 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<ernie::Tensor>(unsigned int, unsigned int):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 107 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::mat<4, 4, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::qua<double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 64 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<2, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<3, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 1557 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<4, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<int>(unsigned int, unsigned int):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 27 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<ernie::Target, std::allocator<ernie::Target> > >(unsigned int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<float, std::allocator<float> > >(unsigned int, unsigned int):
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<unsigned int, std::allocator<unsigned int> > >(unsigned int, unsigned int):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1596 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<unsigned char>(unsigned int, unsigned int):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 13 times.
ernie::Column& ernie::PrimStore::FindOrAddColumn<unsigned int>(unsigned int, unsigned int):
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 116 times.
4984 return found != nullptr ? *found
416
74/148
ernie::Column& ernie::PrimStore::FindOrAddColumn<double>(unsigned int, unsigned int):
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 1213 times.
✓ Branch 9 taken 13 times.
✓ Branch 10 taken 1213 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<ernie::Target>(unsigned int, unsigned int):
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 29 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 29 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<ernie::Tensor>(unsigned int, unsigned int):
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 107 times.
✓ Branch 9 taken 1 time.
✓ Branch 10 taken 107 times.
✓ Branch 11 taken 1 time.
✓ Branch 12 taken 107 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::mat<4, 4, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 16 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::qua<double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 64 times.
✓ Branch 9 taken 15 times.
✓ Branch 10 taken 64 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<2, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<3, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 117 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 117 times.
✓ Branch 7 taken 1557 times.
✓ Branch 9 taken 117 times.
✓ Branch 10 taken 1557 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<glm::vec<4, double, (glm::qualifier)0> >(unsigned int, unsigned int):
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<int>(unsigned int, unsigned int):
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 27 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 27 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<ernie::Target, std::allocator<ernie::Target> > >(unsigned int, unsigned int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 22 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 22 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 22 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<float, std::allocator<float> > >(unsigned int, unsigned int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 21 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 21 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 21 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<std::vector<unsigned int, std::allocator<unsigned int> > >(unsigned int, unsigned int):
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1596 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1596 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 1596 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<unsigned char>(unsigned int, unsigned int):
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 13 times.
✓ Branch 9 taken 1 time.
✓ Branch 10 taken 13 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
ernie::Column& ernie::PrimStore::FindOrAddColumn<unsigned int>(unsigned int, unsigned int):
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 116 times.
✓ Branch 9 taken 19 times.
✓ Branch 10 taken 116 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5176 : AddColumn(b, attribute, std::make_unique<TypedColumn<T>>(T{}));
417 }
418 /// @throws std::invalid_argument if the column holds another type.
419 54770 template <typename T> static const std::vector<T>& Values(const Column& column) {
420
14/28
std::vector<double, std::allocator<double> > const& ernie::PrimStore::Values<double>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 1732 times.
std::vector<ernie::Target, std::allocator<ernie::Target> > const& ernie::PrimStore::Values<ernie::Target>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
std::vector<ernie::Tensor, std::allocator<ernie::Tensor> > const& ernie::PrimStore::Values<ernie::Tensor>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 87 times.
std::vector<glm::mat<4, 4, double, (glm::qualifier)0>, std::allocator<glm::mat<4, 4, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::mat<4, 4, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
std::vector<glm::qua<double, (glm::qualifier)0>, std::allocator<glm::qua<double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::qua<double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
std::vector<glm::vec<2, double, (glm::qualifier)0>, std::allocator<glm::vec<2, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<2, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
std::vector<glm::vec<3, double, (glm::qualifier)0>, std::allocator<glm::vec<3, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<3, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 6228 times.
std::vector<glm::vec<4, double, (glm::qualifier)0>, std::allocator<glm::vec<4, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<4, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
std::vector<int, std::allocator<int> > const& ernie::PrimStore::Values<int>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
std::vector<std::vector<ernie::Target, std::allocator<ernie::Target> >, std::allocator<std::vector<ernie::Target, std::allocator<ernie::Target> > > > const& ernie::PrimStore::Values<std::vector<ernie::Target, std::allocator<ernie::Target> > >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > > const& ernie::PrimStore::Values<std::vector<float, std::allocator<float> > >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 57 times.
std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > > const& ernie::PrimStore::Values<std::vector<unsigned int, std::allocator<unsigned int> > >(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 8339 times.
std::vector<unsigned char, std::allocator<unsigned char> > const& ernie::PrimStore::Values<unsigned char>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
std::vector<unsigned int, std::allocator<unsigned int> > const& ernie::PrimStore::Values<unsigned int>(ernie::Column const&):
✗ Branch 1 not taken.
✓ Branch 2 taken 86 times.
54770 if (column.values->Type() != kColumnType<T>) {
421
0/28
std::vector<double, std::allocator<double> > const& ernie::PrimStore::Values<double>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<ernie::Target, std::allocator<ernie::Target> > const& ernie::PrimStore::Values<ernie::Target>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<ernie::Tensor, std::allocator<ernie::Tensor> > const& ernie::PrimStore::Values<ernie::Tensor>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<glm::mat<4, 4, double, (glm::qualifier)0>, std::allocator<glm::mat<4, 4, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::mat<4, 4, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<glm::qua<double, (glm::qualifier)0>, std::allocator<glm::qua<double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::qua<double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<glm::vec<2, double, (glm::qualifier)0>, std::allocator<glm::vec<2, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<2, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<glm::vec<3, double, (glm::qualifier)0>, std::allocator<glm::vec<3, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<3, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<glm::vec<4, double, (glm::qualifier)0>, std::allocator<glm::vec<4, double, (glm::qualifier)0> > > const& ernie::PrimStore::Values<glm::vec<4, double, (glm::qualifier)0> >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<int, std::allocator<int> > const& ernie::PrimStore::Values<int>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<std::vector<ernie::Target, std::allocator<ernie::Target> >, std::allocator<std::vector<ernie::Target, std::allocator<ernie::Target> > > > const& ernie::PrimStore::Values<std::vector<ernie::Target, std::allocator<ernie::Target> > >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > > const& ernie::PrimStore::Values<std::vector<float, std::allocator<float> > >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > > const& ernie::PrimStore::Values<std::vector<unsigned int, std::allocator<unsigned int> > >(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<unsigned char, std::allocator<unsigned char> > const& ernie::PrimStore::Values<unsigned char>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
std::vector<unsigned int, std::allocator<unsigned int> > const& ernie::PrimStore::Values<unsigned int>(ernie::Column const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 throw std::invalid_argument("The column holds another type");
422 }
423 54769 return static_cast<const TypedColumn<T>&>(*column.values).Values();
424 }
425 33219 template <typename T> static std::vector<T>& Values(Column& column) {
426 33219 return const_cast<std::vector<T>&>(Values<T>(std::as_const(column)));
427 }
428
429 PathTable paths_;
430 std::vector<std::unique_ptr<Bucket>> buckets_;
431 std::unordered_map<BucketKey, BucketId, KeyHash> bucketIndex_;
432 std::vector<SlotData> slots_;
433 std::vector<std::uint32_t> free_;
434 /// The prim slot of each path, or none.
435 std::vector<std::uint32_t> pathSlots_;
436 std::uint64_t version_ = 0;
437 };
438
439 } // namespace ernie
440