Fenix @develop
 
Loading...
Searching...
No Matches
mstream.hpp
1#ifndef FENIX_DATA_MSTREAM_HPP
2#define FENIX_DATA_MSTREAM_HPP
3
4#include <streambuf>
5#include <iostream>
6#include <memory>
7
8#include "fenix/data/util/data_ref.hpp"
9
10namespace fenix::data::util {
11namespace detail {
12
13class OMmapStreamBuf : public std::streambuf {
14 public:
15 using std::streambuf::int_type;
16 using std::streambuf::off_type;
17 using std::streambuf::pos_type;
18 using Traits = std::char_traits<char>;
19
20#ifdef FENIX_HAVE_MREMAP
21 // Bytes of virtual address space claimed at a time
22 static inline size_t target_claim_chunk_size = 1024 * 1024 * 1024; // 1GB
23#else
24 // If we can't mremap, claim more virtual address space at once, since we
25 // can't grow
26 static inline size_t target_claim_chunk_size =
27 20ULL * 1024 * 1024 * 1024; // 20GB
28#endif
29
30 // Bytes of claimed address space made writable at a time
31 static inline size_t target_write_chunk_size = 1024 * 1024; // 1MB
32
34 ~OMmapStreamBuf() override;
35
36 size_t written_len();
37
38 // If FENIX_HAVE_MREMAP, user responsible for calling munmap on released buf.
39 // Otherwise, user responsible for calling free on released buf.
40 char* release();
41
42 protected:
43 int_type overflow(int_type ch) override;
44 pos_type seekpos(pos_type pos, std::ios_base::openmode which) override;
45 pos_type seekoff(
46 off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which
47 ) override;
48
49 private:
50 void grow_len(size_t& len, size_t chunk, size_t target);
51 void ensure_space(size_t needed_len);
52
53 char* mmap_address = nullptr;
54 size_t claim_len = 0;
55 size_t writable_len = 0;
56 size_t written_highwater = 0;
57
58 size_t claim_chunk_size, write_chunk_size;
59};
60
61class MStreamBuf : public std::streambuf {
62 public:
63 using std::streambuf::int_type;
64 using std::streambuf::off_type;
65 using std::streambuf::pos_type;
66 using Traits = std::char_traits<char>;
67
68 MStreamBuf(char* buf, size_t len);
69 ~MStreamBuf() = default;
70
71 protected:
72 int_type overflow(int_type ch) override;
73 pos_type seekpos(pos_type pos, std::ios_base::openmode which) override;
74 pos_type seekoff(
75 off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which
76 ) override;
77
78 private:
79 char* buf = nullptr;
80 size_t len = 0;
81};
82
83} //namespace detail
84
85class MStream : public std::iostream {
86 public:
87 // Dynamically sized MStream, will need its streambuf's data released
88 MStream() : std::iostream(nullptr) {
89 buf = std::make_unique<detail::OMmapStreamBuf>();
90 rdbuf(buf.get());
91 }
92
93 // Statically sized MStream pointing to dr
94 MStream(const DataRef& dr) : std::iostream(nullptr) {
95 buf = std::make_unique<detail::MStreamBuf>(dr.data(), dr.size());
96 rdbuf(buf.get());
97 }
98
99 MStream(MStream&& o) : std::iostream(nullptr) {
100 o.rdbuf(nullptr);
101 buf = std::move(o.buf);
102 rdbuf(buf.get());
103 }
104 ~MStream() = default;
105
106 std::streambuf* get_buf() { return buf.get(); }
107
108 private:
109 std::unique_ptr<std::streambuf> buf;
110};
111
112} //namespace fenix::data::util
113
114#endif
Definition data_ref.hpp:50
Definition mstream.hpp:85
Definition mstream.hpp:61