simdjson  3.1.6
Ridiculously Fast JSON
document_stream.h
1 #include "simdjson/error.h"
2 #ifdef SIMDJSON_THREADS_ENABLED
3 #include <thread>
4 #include <mutex>
5 #include <condition_variable>
6 #endif
7 
8 namespace simdjson {
9 namespace SIMDJSON_IMPLEMENTATION {
10 namespace ondemand {
11 
12 class parser;
13 class json_iterator;
14 class document;
15 
16 #ifdef SIMDJSON_THREADS_ENABLED
18 struct stage1_worker {
19  stage1_worker() noexcept = default;
20  stage1_worker(const stage1_worker&) = delete;
21  stage1_worker(stage1_worker&&) = delete;
22  stage1_worker operator=(const stage1_worker&) = delete;
23  ~stage1_worker();
28  void start_thread();
33  void run(document_stream * ds, parser * stage1, size_t next_batch_start);
35  void finish();
36 
37 private:
38 
44  void stop_thread();
45 
46  std::thread thread{};
48  ondemand::parser * stage1_thread_parser{};
49  size_t _next_batch_start{};
50  document_stream * owner{};
55  bool has_work{false};
56  bool can_work{true};
57 
61  std::mutex locking_mutex{};
62  std::condition_variable cond_var{};
63 
64  friend class document_stream;
65 };
66 #endif // SIMDJSON_THREADS_ENABLED
67 
75 public:
84  simdjson_inline document_stream() noexcept;
86  simdjson_inline document_stream(document_stream &&other) noexcept = default;
88  simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default;
89 
90  simdjson_inline ~document_stream() noexcept;
91 
95  inline size_t size_in_bytes() const noexcept;
96 
115  inline size_t truncated_bytes() const noexcept;
116 
117  class iterator {
118  public:
120  using reference = value_type;
121 
122  using difference_type = std::ptrdiff_t;
123 
124  using iterator_category = std::input_iterator_tag;
125 
129  simdjson_inline iterator() noexcept;
133  simdjson_inline simdjson_result<ondemand::document_reference> operator*() noexcept;
137  inline iterator& operator++() noexcept;
142  simdjson_inline bool operator!=(const iterator &other) const noexcept;
158  simdjson_inline size_t current_index() const noexcept;
159 
179  simdjson_inline std::string_view source() const noexcept;
180 
184  inline error_code error() const noexcept;
185 
186  private:
187  simdjson_inline iterator(document_stream *s, bool finished) noexcept;
189  document_stream* stream;
191  bool finished;
192 
193  friend class document;
194  friend class document_stream;
195  friend class json_iterator;
196  };
197 
201  simdjson_inline iterator begin() noexcept;
205  simdjson_inline iterator end() noexcept;
206 
207 private:
208 
209  document_stream &operator=(const document_stream &) = delete; // Disallow copying
210  document_stream(const document_stream &other) = delete; // Disallow copying
211 
221  simdjson_inline document_stream(
222  ondemand::parser &parser,
223  const uint8_t *buf,
224  size_t len,
225  size_t batch_size
226  ) noexcept;
227 
232  inline void start() noexcept;
233 
258  inline void next() noexcept;
259 
261  inline void next_document() noexcept;
262 
264  inline size_t next_batch_start() const noexcept;
265 
267  inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept;
268 
269  // Fields
270  ondemand::parser *parser;
271  const uint8_t *buf;
272  size_t len;
273  size_t batch_size;
279  document doc{};
281  error_code error;
282  size_t batch_start{0};
283  size_t doc_index{};
284 
285  #ifdef SIMDJSON_THREADS_ENABLED
287  bool use_thread;
288 
289  inline void load_from_stage1_thread() noexcept;
290 
292  inline void start_stage1_thread() noexcept;
293 
295  inline void finish_stage1_thread() noexcept;
296 
298  error_code stage1_thread_error{UNINITIALIZED};
300  std::unique_ptr<stage1_worker> worker{new(std::nothrow) stage1_worker()};
305  ondemand::parser stage1_thread_parser{};
306 
307  friend struct stage1_worker;
308  #endif // SIMDJSON_THREADS_ENABLED
309 
310  friend class parser;
311  friend class document;
312  friend class json_iterator;
313  friend struct simdjson_result<ondemand::document_stream>;
314  friend struct internal::simdjson_result_base<ondemand::document_stream>;
315 }; // document_stream
316 
317 } // namespace ondemand
318 } // namespace SIMDJSON_IMPLEMENTATION
319 } // namespace simdjson
320 
321 namespace simdjson {
322 template<>
323 struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_stream> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::document_stream> {
324 public:
325  simdjson_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::document_stream &&value) noexcept;
326  simdjson_inline simdjson_result(error_code error) noexcept;
327  simdjson_inline simdjson_result() noexcept = default;
328 };
329 
330 } // namespace simdjson
simdjson_inline iterator end() noexcept
The end of the stream, for iterator comparison purposes.
simdjson_inline document_stream(document_stream &&other) noexcept=default
Move one document_stream to another.
size_t size_in_bytes() const noexcept
Returns the input size in bytes.
simdjson_inline document_stream & operator=(document_stream &&other) noexcept=default
Move one document_stream to another.
size_t truncated_bytes() const noexcept
After iterating through the stream, this method returns the number of bytes that were not parsed at t...
simdjson_inline iterator begin() noexcept
Start iterating the documents in the stream.
simdjson_inline document_stream() noexcept
Construct an uninitialized document_stream.
We want to support argument-dependent lookup (ADL).
error_code
All possible errors returned by simdjson.
Definition: error.h:17
@ UNINITIALIZED
unknown error, or uninitialized document
Definition: error.h:29
The result of a simdjson operation that could fail.
Definition: error.h:205