• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17846711083

19 Sep 2025 02:28AM UTC coverage: 72.02% (+0.08%) from 71.942%
17846711083

push

github

paulmthompson
event in interval computer works with entity ids

259 of 280 new or added lines in 6 files covered. (92.5%)

268 existing lines in 17 files now uncovered.

40247 of 55883 relevant lines covered (72.02%)

1227.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.71
/src/DataManager/utils/TableView/core/TableView.h
1
#ifndef TABLE_VIEW_H
2
#define TABLE_VIEW_H
3

4
#include "utils/TableView/columns/ColumnTypeInfo.hpp"
5
#include "utils/TableView/columns/Column.h"
6
#include "utils/TableView/core/ExecutionPlan.h"
7
#include "utils/TableView/core/RowDescriptor.h"
8

9
#include <map>
10
#include <memory>
11
#include <set>
12
#include <span>
13
#include <stdexcept>
14
#include <string>
15
#include <vector>
16

17
class DataManagerExtension;
18
class IColumn;
19
class IRowSelector;
20
class TableViewBuilder;
21

22
/**
23
 * @brief The main orchestrator for tabular data views with lazy evaluation.
24
 * 
25
 * TableView manages a collection of heterogeneous columns and provides unified 
26
 * access to tabular data. It implements lazy evaluation with caching for both 
27
 * individual columns and ExecutionPlans. The TableView handles dependency 
28
 * resolution and ensures columns are computed in the correct order.
29
 */
30
class TableView {
31
public:
32

33
    // Movable but not copyable
34
    TableView(TableView && other) noexcept;
35
    TableView & operator=(TableView && other);
36
    TableView(const TableView & other) = delete;
37
    TableView & operator=(const TableView & other) = delete;
38

39
    /**
40
     * @brief Gets the number of rows in the table.
41
     * @return The row count as determined by the row selector.
42
     */
43
    [[nodiscard]] auto getRowCount() const -> size_t;
44

45
    /**
46
     * @brief Gets the number of columns in the table.
47
     * @return The column count.
48
     */
49
    [[nodiscard]] auto getColumnCount() const -> size_t;
50

51
    /**
52
     * @brief Gets the values of a column with the specified type.
53
     * 
54
     * This method provides type-safe access to column data. It performs a
55
     * dynamic_cast to ensure the column is of the correct type, and triggers
56
     * computation if the column is not yet materialized.
57
     * 
58
     * @tparam T The expected type of the column data.
59
     * @param name The name of the column to retrieve.
60
     * @return Reference to the column's data vector.
61
     * @throws std::runtime_error if the column is not found or type mismatch.
62
     */
63
    template<SupportedColumnType T>
64
    [[nodiscard]] auto getColumnValues(std::string const & name) -> std::vector<T> const &;
65

66
    /**
67
     * @brief Gets the names of all columns in the table.
68
     * @return Vector of column names.
69
     */
70
    [[nodiscard]] auto getColumnNames() const -> std::vector<std::string>;
71

72
    /**
73
     * @brief Checks if a column exists in the table.
74
     * @param name The column name to check.
75
     * @return True if the column exists, false otherwise.
76
     */
77
    [[nodiscard]] auto hasColumn(std::string const & name) const -> bool;
78

79
    /**
80
     * @brief Gets the runtime type information for a column.
81
     * @param name The column name.
82
     * @return The std::type_info for the column's data type.
83
     * @throws std::runtime_error if the column is not found.
84
     */
85
    [[nodiscard]] auto getColumnType(std::string const & name) const -> std::type_info const &;
86

87
    /**
88
     * @brief Gets the type index for a column.
89
     * @param name The column name.
90
     * @return The std::type_index for the column's data type.
91
     * @throws std::runtime_error if the column is not found.
92
     */
93
    [[nodiscard]] auto getColumnTypeIndex(std::string const & name) const -> std::type_index;
94

95
    /**
96
     * @brief Gets column data as a variant, avoiding try/catch for type detection.
97
     * 
98
     * This method returns column data in a type-safe variant that contains
99
     * all possible column types. Consumers can use std::visit or pattern
100
     * matching to handle the data without try/catch blocks.
101
     * 
102
     * @param name The column name.
103
     * @return ColumnDataVariant containing the column data.
104
     * @throws std::runtime_error if the column is not found or type not supported.
105
     */
106
    [[nodiscard]] auto getColumnDataVariant(std::string const & name) -> ColumnDataVariant;
107

108
    /**
109
     * @brief Applies a visitor to column data in a type-safe manner.
110
     * @tparam Visitor The visitor type that implements visit methods for all supported types.
111
     * @param name The column name.
112
     * @param visitor The visitor instance.
113
     * @return The result of the visitor.
114
     * @throws std::runtime_error if the column is not found or type not supported.
115
     */
116
    template<typename Visitor>
117
    auto visitColumnData(std::string const & name, Visitor&& visitor) -> decltype(auto);
118

119
    /**
120
     * @brief Materializes all columns in the table.
121
     * 
122
     * This method computes all columns that haven't been materialized yet.
123
     * It respects dependencies and computes columns in the correct order.
124
     */
125
    void materializeAll();
126

127
    /**
128
     * @brief Clears all cached data, forcing recomputation on next access.
129
     */
130
    void clearCache();
131

132
    /**
133
     * @brief Gets a descriptor containing the source information for a given row index.
134
     * 
135
     * This method provides reverse lookup capability, allowing clients to trace
136
     * a row back to its original source definition (e.g., timestamp, interval).
137
     * This is particularly useful for interactive applications like plotting libraries
138
     * that need to display tooltips or navigate back to source data.
139
     * 
140
     * @param row_index The index of the row to get the descriptor for.
141
     * @return RowDescriptor containing the source information for the row.
142
     */
143
    [[nodiscard]] auto getRowDescriptor(size_t row_index) const -> RowDescriptor;
144

145
    /**
146
     * @brief Get contributing EntityIds for a given row, if available.
147
     * @return Vector of EntityIds; empty if not available.
148
     */
149
    [[nodiscard]] auto getRowEntityIds(size_t row_index) const -> std::vector<EntityId>;
150

151
    /**
152
     * @brief Check if this table has EntityID information available.
153
     * @return True if EntityIDs are available for rows, false otherwise.
154
     */
155
    [[nodiscard]] bool hasEntityColumn() const;
156

157
    /**
158
     * @brief Get all EntityIds for all rows in the table.
159
     * 
160
     * For tables where each row corresponds to a single entity, this returns
161
     * a vector with one EntityId per row. For tables where rows can have multiple
162
     * contributing entities, this returns the primary EntityId for each row.
163
     * 
164
     * @return Vector of EntityIds, one per row. Empty vector if no EntityIDs available.
165
     */
166
    [[nodiscard]] auto getEntityIds() const -> std::vector<EntityId>;
167

168
    /**
169
     * @brief Set EntityIds directly for transformed tables.
170
     * 
171
     * This method allows transforms to preserve EntityId information
172
     * when creating new tables that don't have execution plans linking
173
     * back to original data sources.
174
     * 
175
     * @param entity_ids Vector of EntityIds, one per row
176
     */
177
    void setDirectEntityIds(std::vector<EntityId> entity_ids);
178

179
    /**
180
     * @brief Check if a specific column has EntityID information available.
181
     * @param name The column name to check.
182
     * @return True if EntityIDs are available for this column, false otherwise.
183
     */
184
    [[nodiscard]] bool hasColumnEntityIds(std::string const & name) const;
185

186
    /**
187
     * @brief Get EntityIds for a specific column.
188
     * 
189
     * This method returns EntityIDs that correspond to the data sources
190
     * used to compute the specified column's values. Each EntityID corresponds
191
     * to a row in the table.
192
     * 
193
     * @param name The column name.
194
     * @return Vector of EntityIds, one per row. Empty if not available.
195
     * @throws std::runtime_error if the column is not found.
196
     */
197
    [[nodiscard]] ColumnEntityIds getColumnEntityIds(std::string const & name) const;
198

199
    /**
200
     * @brief Get all contributing EntityIDs for a specific cell.
201
     * 
202
     * This method returns all EntityIDs that contributed to the computation
203
     * of a specific cell in the table. For simple columns, this will return
204
     * the same as getColumnEntityIds()[row_index]. For complex columns that
205
     * aggregate data from multiple entities, this may return multiple EntityIDs.
206
     * 
207
     * @param column_name The column name.
208
     * @param row_index The row index.
209
     * @return Vector of EntityIDs that contributed to this cell. Empty if not available.
210
     * @throws std::runtime_error if the column is not found or row_index is out of bounds.
211
     */
212
    [[nodiscard]] auto getCellEntityIds(std::string const & column_name, size_t row_index) const -> std::vector<EntityId>;
213

214
    /**
215
     * @brief Create a new row selector of the same concrete type, filtered to a subset of rows.
216
     *
217
     * @param keep_indices Indices of rows to keep (relative to this table's current rows), in ascending order.
218
     * @return A new row selector that preserves the original selector's semantics while containing only the kept rows.
219
     */
220
    [[nodiscard]] auto cloneRowSelectorFiltered(std::vector<size_t> const & keep_indices) const -> std::unique_ptr<IRowSelector>;
221

222
    /**
223
     * @brief Access the data manager extension backing this table.
224
     * @return Shared pointer to the `DataManagerExtension`.
225
     */
226
    [[nodiscard]] auto getDataManagerExtension() const -> std::shared_ptr<DataManagerExtension> { return m_dataManager; }
2✔
227

228
private:
229
    friend class TableViewBuilder;
230
    // Grant friend access to the templated Column class
231
    template<SupportedColumnType T>
232
    friend class Column;
233

234
    /**
235
     * @brief Private constructor for TableViewBuilder.
236
     * @param rowSelector The row selector defining table rows.
237
     * @param dataManager The data manager for accessing data sources.
238
     */
239
    TableView(std::unique_ptr<IRowSelector> rowSelector,
240
              std::shared_ptr<DataManagerExtension> dataManager);
241

242
    /**
243
     * @brief Gets or creates the ExecutionPlan for a given data source.
244
     * 
245
     * This method is critical for the caching system. It checks the plan cache
246
     * first, and if not found, uses the IRowSelector to generate the necessary
247
     * indices for the given data source, then stores the new plan in the cache.
248
     * 
249
     * @param sourceName The name of the data source (e.g., "LFP", "Spikes.x").
250
     * @return Reference to the ExecutionPlan for the source.
251
     */
252
    [[nodiscard]] auto getExecutionPlanFor(std::string const & sourceName) -> ExecutionPlan const &;
253

254
    /**
255
     * @brief Adds a column to the table.
256
     * @param column Shared pointer to the column to add.
257
     * @throws std::runtime_error if a column with the same name already exists.
258
     */
259
    void addColumn(std::shared_ptr<IColumn> column);
260

261
    /**
262
     * @brief Materializes a column and its dependencies.
263
     * 
264
     * This method ensures that all dependencies are materialized before
265
     * materializing the target column. It handles circular dependency detection.
266
     * 
267
     * @param columnName The name of the column to materialize.
268
     * @param materializing Set of columns currently being materialized (for cycle detection).
269
     */
270
    void materializeColumn(std::string const & columnName, std::set<std::string> & materializing);
271

272
    /**
273
     * @brief Generates an ExecutionPlan for a specific data source.
274
     * 
275
     * This method uses the row selector to create the appropriate ExecutionPlan
276
     * based on the type of row selector and the requirements of the data source.
277
     * 
278
     * @param sourceName The name of the data source.
279
     * @return The generated ExecutionPlan.
280
     */
281
    [[nodiscard]] auto generateExecutionPlan(std::string const & sourceName) -> ExecutionPlan;
282

283
    std::unique_ptr<IRowSelector> m_rowSelector;
284
    std::shared_ptr<DataManagerExtension> m_dataManager;
285
    std::vector<std::shared_ptr<IColumn>> m_columns;
286
    std::map<std::string, size_t> m_colNameToIndex;
287

288
    // Caches ExecutionPlans, keyed by data source name
289
    std::map<std::string, ExecutionPlan> m_planCache;
290
    
291
    // Direct EntityId storage for transformed tables
292
    std::vector<EntityId> m_direct_entity_ids;
293
};
294

295
// Template method implementation for getColumnValues
296
template<SupportedColumnType T>
297
auto TableView::getColumnValues(std::string const & name) -> std::vector<T> const & {
298✔
298
    // 1. Find the IColumn pointer by name
299
    auto it = m_colNameToIndex.find(name);
298✔
300
    if (it == m_colNameToIndex.end()) {
298✔
UNCOV
301
        throw std::runtime_error("Column '" + name + "' not found in table");
×
302
    }
303

304
    // 2. Get the column and attempt dynamic_cast to Column<T>
305
    auto & column = m_columns[it->second];
298✔
306
    auto * typedColumn = dynamic_cast<Column<T> *>(column.get());
298✔
307

308
    // 3. If cast fails, throw exception for type mismatch
309
    if (!typedColumn) {
298✔
UNCOV
310
        throw std::runtime_error("Column '" + name + "' is not of the requested type");
×
311
    }
312

313
    // 4. Call getValues on the typed column
314
    return typedColumn->getValues(this);
596✔
315
}
316

317
// Template method implementation for visitColumnData
318
template<typename Visitor>
319
auto TableView::visitColumnData(std::string const & name, Visitor&& visitor) -> decltype(auto) {
118✔
320
    auto variant = getColumnDataVariant(name);
118✔
321
    return std::visit(std::forward<Visitor>(visitor), variant);
236✔
322
}
118✔
323

324
#endif// TABLE_VIEW_H
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc