iceberg-cpp
Loading...
Searching...
No Matches
stream.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <cstddef>
26#include <deque>
27#include <memory>
28#include <optional>
29#include <type_traits>
30#include <utility>
31#include <vector>
32
33#include "iceberg/result.h"
34
35namespace iceberg {
36
46template <typename T>
47class Stream {
48 public:
50 virtual ~Stream() = default;
51
53 Stream() = default;
54
56 Stream(const Stream&) = delete;
57
59 Stream& operator=(const Stream&) = delete;
60
62 Stream(Stream&&) noexcept = default;
63
65 Stream& operator=(Stream&&) noexcept = default;
66
68 static std::unique_ptr<Stream<T>> FromVector(std::vector<T> values);
69
74 Result<std::optional<T>> Next() {
75 if (error_.has_value()) {
76 return unexpected(*error_);
77 }
78 if (finished_) {
79 return std::nullopt;
80 }
81
82 auto result = NextImpl();
83 if (!result.has_value()) {
84 error_ = result.error();
85 } else if (!result.value().has_value()) {
86 finished_ = true;
87 }
88 return result;
89 }
90
93 auto collect = [this](auto& values, auto append,
94 auto finish) -> Result<std::vector<T>> {
95 while (true) {
96 auto result = Next();
97 if (!result.has_value()) {
98 return unexpected(std::move(result.error()));
99 }
100 auto& value = result.value();
101 if (!value.has_value()) {
102 return finish(values);
103 }
104 append(values, value.value());
105 }
106 };
107
108 if constexpr (!std::is_move_constructible_v<T>) {
109 static_assert(std::is_copy_constructible_v<T>,
110 "Stream::ToVector requires T to be move- or copy-constructible");
111
112 // For strictly copy-only T, collecting directly into a vector can repeatedly copy
113 // previously collected elements during vector growth. Stage values in a deque,
114 // then copy once into an exactly sized vector.
115 std::deque<T> values;
116 return collect(
117 values, [](auto& destination, const T& value) { destination.push_back(value); },
118 [](const auto& source) {
119 return std::vector<T>(source.cbegin(), source.cend());
120 });
121 } else {
122 std::vector<T> values;
123 return collect(
124 values,
125 [](auto& destination, T& value) {
126 destination.push_back(std::move_if_noexcept(value));
127 },
128 [](auto& source) { return std::move(source); });
129 }
130 }
131
132 protected:
138
139 private:
140 bool finished_ = false;
141 std::optional<Error> error_;
142};
143
144template <typename T>
145std::unique_ptr<Stream<T>> Stream<T>::FromVector(std::vector<T> values) {
146 class VectorStream final : public Stream<T> {
147 public:
148 explicit VectorStream(std::vector<T> values) : values_(std::move(values)) {}
149
150 protected:
151 Result<std::optional<T>> NextImpl() override {
152 if (index_ == values_.size()) {
153 return std::nullopt;
154 }
155 auto&& value = values_[index_++];
156 return Result<std::optional<T>>(std::in_place, std::in_place,
157 std::move_if_noexcept(value));
158 }
159
160 private:
161 std::vector<T> values_;
162 size_t index_ = 0;
163 };
164 return std::make_unique<VectorStream>(std::move(values));
165}
166
167} // namespace iceberg
A pull-based stream whose reads may fail.
Definition stream.h:47
virtual Result< std::optional< T > > NextImpl()=0
Produce the next value for Next().
Stream()=default
Construct a stream in its initial state.
virtual ~Stream()=default
Destroy this stream and release its producer resources.
static std::unique_ptr< Stream< T > > FromVector(std::vector< T > values)
Create a stream that owns and consumes the given values in order.
Definition stream.h:145
Stream(const Stream &)=delete
Streams cannot be copied.
Stream(Stream &&) noexcept=default
Move a stream and its terminal state.
Stream & operator=(const Stream &)=delete
Streams cannot be copy-assigned.
Result< std::vector< T > > ToVector()
Consume the remaining values into a vector.
Definition stream.h:92
Result< std::optional< T > > Next()
Return the next value, or std::nullopt when the stream is exhausted.
Definition stream.h:74
Definition expected.h:1199
Definition expected.h:246
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:34
STL namespace.
Define Result, Status, and error helpers.