Joedb 10.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
File_Buffer.h
Go to the documentation of this file.
1#ifndef joedb_File_Buffer_declared
2#define joedb_File_Buffer_declared
3
7#include "joedb/index_types.h"
8
9#include <string>
10
11namespace joedb
12{
13 /// @ingroup journal
15 {
16 private:
17 Buffer<12> buffer;
18
19 size_t read_buffer_size;
20
21 //////////////////////////////////////////////////////////////////////////
22 bool buffer_has_write_data() const noexcept
23 //////////////////////////////////////////////////////////////////////////
24 {
25 return buffer.index > 0 && !read_buffer_size;
26 }
27
28 //////////////////////////////////////////////////////////////////////////
29 bool buffer_has_read_data() const
30 //////////////////////////////////////////////////////////////////////////
31 {
32 return read_buffer_size;
33 }
34
35 //////////////////////////////////////////////////////////////////////////
36 void read_buffer()
37 //////////////////////////////////////////////////////////////////////////
38 {
39 JOEDB_DEBUG_ASSERT(!buffer_has_write_data());
40 JOEDB_DEBUG_ASSERT(buffer.index <= read_buffer_size);
41
42 buffer.index = 0;
43 read_buffer_size = File_Iterator::read(buffer.data, buffer.size);
44 if (read_buffer_size == 0)
45 file.reading_past_end_of_file();
46 }
47
48 //////////////////////////////////////////////////////////////////////////
49 void write_buffer()
50 //////////////////////////////////////////////////////////////////////////
51 {
52 JOEDB_DEBUG_ASSERT(!buffer_has_read_data());
53
54 File_Iterator::write(buffer.data, buffer.index);
55 buffer.index = 0;
56 }
57
58 //////////////////////////////////////////////////////////////////////////
59 void check_write_buffer()
60 //////////////////////////////////////////////////////////////////////////
61 {
62 JOEDB_DEBUG_ASSERT(!buffer_has_read_data());
63
64 if (buffer.index >= buffer.size)
65 write_buffer();
66 }
67
68 public:
70 void flush();
71
72 // set_position must be called when switching between write and read
73 void set_position(int64_t position);
74
75 int64_t get_position() const noexcept
76 {
77 return File_Iterator::get_position() - read_buffer_size + buffer.index;
78 }
79
80 //////////////////////////////////////////////////////////////////////////
81 template<typename T> void write(T x)
82 //////////////////////////////////////////////////////////////////////////
83 {
84 static_assert(sizeof(T) <= decltype(buffer)::extra_size);
85 buffer.write<T>(x);
86 check_write_buffer();
87 }
88
89 //////////////////////////////////////////////////////////////////////////
90 template<typename T> T read()
91 //////////////////////////////////////////////////////////////////////////
92 {
93 T result;
94 read_data(reinterpret_cast<char *>(&result), sizeof(result));
95 return result;
96 }
97
98 //////////////////////////////////////////////////////////////////////////
99 template<typename T> void compact_write(T x)
100 //////////////////////////////////////////////////////////////////////////
101 {
102 buffer.compact_write<T>(x);
103 check_write_buffer();
104 }
105
106 //////////////////////////////////////////////////////////////////////////
107 template<typename T> T compact_read()
108 //////////////////////////////////////////////////////////////////////////
109 {
110 if (buffer.index + 8 <= read_buffer_size)
111 return buffer.compact_read<T>();
112
113 const uint8_t first_byte = read<uint8_t>();
114#ifdef JOEDB_DIRTY_WORKAROUND
115 if (first_byte == 0xff)
116 return 0;
117#endif
118 int extra_bytes = first_byte >> 5;
119 T result = first_byte & 0x1f;
120 while (--extra_bytes >= 0)
121 result = T((result << 8) | read<uint8_t>());
122 return result;
123 }
124
125 template<typename T> T read_strong_type()
126 {
127 return T(compact_read<typename underlying_type<T>::type>());
128 }
129
131 {
133 }
134
139
140 void write_string(std::string_view s);
141 std::string read_string();
142 std::string safe_read_string(int64_t max_size);
143
144 void write_blob(Blob blob)
145 {
148 }
149
151 {
152 const int64_t position = compact_read<int64_t>();
153 const int64_t size = compact_read<int64_t>();
154 return Blob(position, size);
155 }
156
157 //////////////////////////////////////////////////////////////////////////
158 void write_data(const char *data, size_t n)
159 //////////////////////////////////////////////////////////////////////////
160 {
161 JOEDB_DEBUG_ASSERT(!buffer_has_read_data());
162
163 if (n <= buffer.extra_size || n < buffer.size + buffer.extra_size - buffer.index)
164 {
165 std::memcpy(buffer.data + buffer.index, data, n);
166 buffer.index += n;
167 check_write_buffer();
168 }
169 else
170 {
171 flush();
172 File_Iterator::write(data, n);
173 }
174 }
175
176 //////////////////////////////////////////////////////////////////////////
177 size_t read_data(char *data, const size_t n)
178 //////////////////////////////////////////////////////////////////////////
179 {
180 JOEDB_DEBUG_ASSERT(!buffer_has_write_data());
181 JOEDB_DEBUG_ASSERT(buffer.index <= read_buffer_size);
182
183 if (buffer.index + n <= read_buffer_size)
184 {
185 std::memcpy(data, buffer.data + buffer.index, n);
186 buffer.index += n;
187 return n;
188 }
189 else
190 {
191 size_t n0 = read_buffer_size - buffer.index;
192 std::memcpy(data, buffer.data + buffer.index, n0);
193 buffer.index += n0;
194
195 if (n <= buffer.size)
196 {
197 read_buffer();
198
199 while (n0 < n && buffer.index < read_buffer_size)
200 data[n0++] = buffer.data[buffer.index++];
201 }
202
203 File_Iterator::full_read(data + n0, n - n0);
204
205 return n;
206 }
207 }
208
209 //////////////////////////////////////////////////////////////////////////
210 void ignore(const int64_t n)
211 //////////////////////////////////////////////////////////////////////////
212 {
213 if (buffer.index + n <= read_buffer_size)
214 buffer.index += n;
215 else
217 }
218
219 ~File_Buffer();
220 };
221}
222
223#endif
int64_t get_position() const noexcept
Definition Blob.h:30
int64_t get_size() const noexcept
Definition Blob.h:31
void write_reference(Record_Id id)
size_t read_data(char *data, const size_t n)
void write_blob(Blob blob)
std::string safe_read_string(int64_t max_size)
void write_data(const char *data, size_t n)
int64_t get_position() const noexcept
Definition File_Buffer.h:75
void ignore(const int64_t n)
File_Buffer(Abstract_File &file)
std::string read_string()
void write_string(std::string_view s)
void compact_write(T x)
Definition File_Buffer.h:99
void set_position(int64_t position)
Record_Id read_reference()
int64_t get_position() const noexcept
void write(const char *data, size_t size)
void full_read(char *data, size_t size)
File_Iterator(Abstract_File &file)
size_t read(char *data, size_t size)
Abstract_File & file
#define JOEDB_DEBUG_ASSERT(x)
assertion tested in debug mode
Definition assert.h:19
constexpr index_t to_underlying(Record_Id id)
Definition index_types.h:59
typename std::underlying_type< T >::type type
Definition index_types.h:51