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

paulmthompson / WhiskerToolbox / 16305883990

15 Jul 2025 10:41PM UTC coverage: 74.374% (-0.2%) from 74.559%
16305883990

push

github

paulmthompson
add time frame conversion method for digital interval series

2 of 2 new or added lines in 1 file covered. (100.0%)

21 existing lines in 3 files now uncovered.

15141 of 20358 relevant lines covered (74.37%)

2100.54 hits per line

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

39.0
/src/WhiskerToolbox/DataManager/utils/TableView/core/TableView.cpp
1
#include "TableView.h"
2

3
#include <algorithm>
4
#include <set>
5
#include <stdexcept>
6

7
TableView::TableView(std::unique_ptr<IRowSelector> rowSelector, 
5✔
8
                     std::shared_ptr<DataManagerExtension> dataManager)
5✔
9
    : m_rowSelector(std::move(rowSelector))
5✔
10
    , m_dataManager(std::move(dataManager))
5✔
11
{
12
    if (!m_rowSelector) {
5✔
13
        throw std::invalid_argument("IRowSelector cannot be null");
×
14
    }
15
    if (!m_dataManager) {
5✔
16
        throw std::invalid_argument("DataManagerExtension cannot be null");
×
17
    }
18
}
5✔
19

20
size_t TableView::getRowCount() const {
3✔
21
    return m_rowSelector->getRowCount();
3✔
22
}
23

24
size_t TableView::getColumnCount() const {
3✔
25
    return m_columns.size();
3✔
26
}
27

28
std::span<const double> TableView::getColumnSpan(const std::string& name) {
8✔
29
    // This method is maintained for backward compatibility with double columns
30
    return std::span<const double>(getColumnValues<double>(name));
8✔
31
}
32

33
std::vector<std::string> TableView::getColumnNames() const {
×
34
    std::vector<std::string> names;
×
35
    names.reserve(m_columns.size());
×
36
    
37
    for (const auto& column : m_columns) {
×
38
        names.push_back(column->getName());
×
39
    }
40
    
41
    return names;
×
42
}
×
43

44
bool TableView::hasColumn(const std::string& name) const {
14✔
45
    return m_colNameToIndex.find(name) != m_colNameToIndex.end();
14✔
46
}
47

48
void TableView::materializeAll() {
×
49
    std::set<std::string> materializing;
×
50
    
51
    for (const auto& column : m_columns) {
×
52
        if (!column->isMaterialized()) {
×
53
            materializeColumn(column->getName(), materializing);
×
54
        }
55
    }
56
}
×
57

58
void TableView::clearCache() {
×
59
    // Clear column caches
60
    for (auto& column : m_columns) {
×
61
        column->clearCache();
×
62
    }
63
    
64
    // Clear execution plan cache
65
    m_planCache.clear();
×
66
}
×
67

68
const ExecutionPlan& TableView::getExecutionPlanFor(const std::string& sourceName) {
10✔
69
    // Check cache first
70
    auto it = m_planCache.find(sourceName);
10✔
71
    if (it != m_planCache.end()) {
10✔
72
        return it->second;
2✔
73
    }
74

75
    // Generate new plan
76
    ExecutionPlan plan = generateExecutionPlan(sourceName);
8✔
77
    
78
    // Store in cache and return reference
79
    auto [insertedIt, inserted] = m_planCache.emplace(sourceName, std::move(plan));
8✔
80
    if (!inserted) {
8✔
81
        throw std::runtime_error("Failed to cache ExecutionPlan for source: " + sourceName);
×
82
    }
83
    
84
    return insertedIt->second;
8✔
85
}
8✔
86

87
void TableView::addColumn(std::shared_ptr<IColumn> column) {
10✔
88
    if (!column) {
10✔
89
        throw std::invalid_argument("Column cannot be null");
×
90
    }
91

92
    const std::string& name = column->getName();
10✔
93
    
94
    // Check for duplicate names
95
    if (hasColumn(name)) {
10✔
96
        throw std::runtime_error("Column '" + name + "' already exists");
×
97
    }
98

99
    // Add to collections
100
    size_t index = m_columns.size();
10✔
101
    m_columns.push_back(std::move(column));
10✔
102
    m_colNameToIndex[name] = index;
10✔
103
}
10✔
104

105
void TableView::materializeColumn(const std::string& columnName, std::set<std::string>& materializing) {
×
106
    // Check for circular dependencies
107
    if (materializing.find(columnName) != materializing.end()) {
×
108
        throw std::runtime_error("Circular dependency detected involving column: " + columnName);
×
109
    }
110

111
    // Check if column exists
112
    if (!hasColumn(columnName)) {
×
113
        throw std::runtime_error("Column '" + columnName + "' not found");
×
114
    }
115

116
    auto& column = m_columns[m_colNameToIndex[columnName]];
×
117
    
118
    // If already materialized, nothing to do
119
    if (column->isMaterialized()) {
×
120
        return;
×
121
    }
122

123
    // Mark as being materialized
124
    materializing.insert(columnName);
×
125

126
    // Materialize dependencies first
127
    const auto dependencies = column->getDependencies();
×
128
    for (const auto& dependency : dependencies) {
×
129
        if (hasColumn(dependency)) {
×
130
            materializeColumn(dependency, materializing);
×
131
        }
132
    }
133

134
    // Materialize this column
135
    column->materialize(this); // Use the IColumn interface method
×
136

137
    // Remove from materializing set
138
    materializing.erase(columnName);
×
139
}
×
140

141
ExecutionPlan TableView::generateExecutionPlan(const std::string& sourceName) {
8✔
142
    // Get the data source to understand its structure
143
    auto dataSource = m_dataManager->getAnalogSource(sourceName);
8✔
144
    if (!dataSource) {
8✔
145
        throw std::runtime_error("Data source '" + sourceName + "' not found");
×
146
    }
147

148
    // Generate plan based on row selector type
149
    // For now, we'll use a simple approach based on the row selector type
150
    
151
    // Check if we have an IntervalSelector
152
    if (auto intervalSelector = dynamic_cast<IntervalSelector*>(m_rowSelector.get())) {
8✔
153
        // Convert intervals to TimeFrameInterval format
154
        const auto& intervals = intervalSelector->getIntervals();
8✔
155
        return ExecutionPlan(intervals);
8✔
156
    }
157
    
158
    // Check if we have a TimestampSelector
159
    if (auto timestampSelector = dynamic_cast<TimestampSelector*>(m_rowSelector.get())) {
×
160
        // Convert timestamps to TimeFrameIndex format
161
        const auto& timestamps = timestampSelector->getTimestamps();
×
162
        std::vector<TimeFrameIndex> indices;
×
163
        indices.reserve(timestamps.size());
×
164
        
165
        for (double timestamp : timestamps) {
×
166
            // For now, assume simple conversion (this would need proper time-to-index conversion)
167
            indices.emplace_back(static_cast<int64_t>(timestamp));
×
168
        }
169
        
170
        return ExecutionPlan(std::move(indices));
×
171
    }
×
172
    
173
    // Check if we have an IndexSelector
174
    if (auto indexSelector = dynamic_cast<IndexSelector*>(m_rowSelector.get())) {
×
175
        // Convert size_t indices to TimeFrameIndex format
176
        const auto& indices = indexSelector->getIndices();
×
177
        std::vector<TimeFrameIndex> timeFrameIndices;
×
178
        timeFrameIndices.reserve(indices.size());
×
179
        
180
        for (size_t index : indices) {
×
181
            timeFrameIndices.emplace_back(static_cast<int64_t>(index));
×
182
        }
183
        
184
        return ExecutionPlan(std::move(timeFrameIndices));
×
185
    }
×
186
    
187
    throw std::runtime_error("Unsupported row selector type for source: " + sourceName);
×
188
}
8✔
189

UNCOV
190
RowDescriptor TableView::getRowDescriptor(size_t row_index) const {
×
UNCOV
191
    if (m_rowSelector) {
×
UNCOV
192
        return m_rowSelector->getDescriptor(row_index);
×
193
    }
UNCOV
194
    return std::monostate{};
×
195
}
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