Skip to content

Commit 2f2eb4b

Browse files
committed
Update API to read multiple Variables
1 parent 0dcd219 commit 2f2eb4b

1 file changed

Lines changed: 53 additions & 6 deletions

File tree

mdio/coordinate_selector.h

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,26 @@ class CoordinateSelector {
8383
explicit CoordinateSelector(Dataset& dataset)
8484
: dataset_(dataset), base_domain_(dataset.domain) {}
8585

86-
template <typename OutT, typename... Ops>
87-
Future<std::vector<OutT>> ReadDataVariable(const std::string& data_variable,
88-
Ops const&... ops) {
89-
// 1) apply filters & sorts in the exact order given
86+
template<typename... OutTs, typename... Ops>
87+
Future<std::tuple<std::vector<OutTs>...>> ReadDataVariables(
88+
std::vector<std::string> const& data_variables,
89+
Ops const&... ops)
90+
{
91+
if (data_variables.size() != sizeof...(OutTs)) {
92+
return absl::InvalidArgumentError(
93+
"ReadDataVariables: number of names must match number of OutTs");
94+
}
95+
// 1) apply all filters & sorts in order
9096
absl::Status st = absl::OkStatus();
9197
((st = st.ok() ? _applyOp(ops).status() : st), ...);
9298
if (!st.ok()) return st;
9399

94-
// 2) finally read out the requested variable
95-
return readSelection<OutT>(data_variable);
100+
// 2) kick off and await all reads
101+
return _readMultiple<OutTs...>(data_variables);
102+
}
103+
104+
void reset() {
105+
kept_runs_.clear();
96106
}
97107

98108
/**
@@ -249,6 +259,43 @@ class CoordinateSelector {
249259
}
250260
}
251261

262+
// helper: expands readSelection<OutTs>(vars[I])...
263+
template<typename... OutTs, std::size_t... I>
264+
Future<std::tuple<std::vector<OutTs>...>> _readMultipleImpl(
265+
std::vector<std::string> const& vars,
266+
std::index_sequence<I...>)
267+
{
268+
// 1) start all reads
269+
auto futs = std::make_tuple(
270+
readSelection<OutTs>(vars[I])...
271+
);
272+
273+
// 2) wait on them in order
274+
absl::Status st = absl::OkStatus();
275+
std::tuple<std::vector<OutTs>...> results;
276+
// fold over I...
277+
(
278+
[&](){
279+
if (!st.ok()) return;
280+
auto& f = std::get<I>(futs);
281+
st = f.status();
282+
if (st.ok()) std::get<I>(results) = std::move(f.value());
283+
}(),
284+
...
285+
);
286+
if (!st.ok()) return st;
287+
return results;
288+
}
289+
290+
template<typename... OutTs>
291+
Future<std::tuple<std::vector<OutTs>...>> _readMultiple(
292+
std::vector<std::string> const& vars)
293+
{
294+
return _readMultipleImpl<OutTs...>(
295+
vars, std::index_sequence_for<OutTs...>{}
296+
);
297+
}
298+
252299
/*
253300
TODO: The built RangeDescriptors aren't behaving as I hoped.
254301
They are building the longest runs possible properly, however

0 commit comments

Comments
 (0)