Joedb 9.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Buffered_File.cpp
Go to the documentation of this file.
4
5namespace joedb
6{
7 //////////////////////////////////////////////////////////////////////////
9 //////////////////////////////////////////////////////////////////////////
10 mode(mode),
11 locked_tail
12 (
13 mode != Open_Mode::shared_write &&
15 )
16 {
17 read_buffer_size = 0;
18 buffer.index = 0;
19 }
20
21 ////////////////////////////////////////////////////////////////////////////
23 ////////////////////////////////////////////////////////////////////////////
24 {
25 if (buffer_has_write_data())
26 write_buffer();
27 read_buffer_size = 0;
28 buffer.index = 0;
29 }
30
31 ////////////////////////////////////////////////////////////////////////////
33 ////////////////////////////////////////////////////////////////////////////
34 {
35 if (buffer.index == read_buffer_size)
36 {
37 read_buffer_size = 0;
38 buffer.index = 0;
39 }
40 }
41
42 ////////////////////////////////////////////////////////////////////////////
43 void Buffered_File::set_position(int64_t new_position)
44 ////////////////////////////////////////////////////////////////////////////
45 {
46 flush();
47 sequential_seek(new_position);
48 }
49
50 ////////////////////////////////////////////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////////////
53 (
54 Buffered_File &destination,
55 const int64_t start,
56 const int64_t size
57 ) const
58 {
59 int64_t done = 0;
60
61 while (done < size)
62 {
63 const size_t asked = std::min(destination.buffer.size, size_t(size - done));
64 const size_t received = pread(destination.buffer.data, asked, start + done);
65
66 if (received == 0)
67 reading_past_end_of_file();
68
69 destination.pwrite(destination.buffer.data, received, start + done);
70 done += int64_t(received);
71 }
72 }
73
74 ////////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////
77 (
78 Buffered_File &destination,
79 const int64_t from,
80 const int64_t until
81 ) const
82 {
83 destination.flush();
84
85 for (int64_t current = from; current < until;)
86 {
87 const size_t half_buffer_size = Buffered_File::buffer.size / 2;
88
89 const size_t n0 = pread
90 (
91 destination.buffer.data,
92 half_buffer_size,
93 current
94 );
95
96 size_t n1 = 0;
97
98 while (n1 < n0)
99 {
100 const size_t n = destination.pread
101 (
102 destination.buffer.data + half_buffer_size + n1,
103 n0 - n1,
104 current
105 );
106
107 if (n == 0)
108 break;
109
110 n1 += n;
111 }
112
113 if (n1 != n0)
114 return false;
115
116 if (n0 == 0)
117 reading_past_end_of_file();
118
119 const int diff = std::memcmp
120 (
121 destination.buffer.data,
122 destination.buffer.data + half_buffer_size,
123 n0
124 );
125
126 if (diff)
127 return false;
128
129 current += int64_t(n0);
130 }
131
132 return true;
133 }
134
135 ////////////////////////////////////////////////////////////////////////////
136 void Buffered_File::write_string(const std::string &s)
137 ////////////////////////////////////////////////////////////////////////////
138 {
139 compact_write<size_t>(s.size());
140 write_data(s.data(), s.size());
141 }
142
143 ////////////////////////////////////////////////////////////////////////////
145 ////////////////////////////////////////////////////////////////////////////
146 {
147 const size_t size = compact_read<size_t>();
148 std::string s(size, 0);
149 read_data(s.data(), size);
150 return s;
151 }
152
153 ////////////////////////////////////////////////////////////////////////////
154 std::string Buffered_File::safe_read_string(int64_t max_size)
155 ////////////////////////////////////////////////////////////////////////////
156 {
157 std::string s;
158 const int64_t size = compact_read<int64_t>();
159 if (size > 0 && size < max_size)
160 {
161 s.resize(size_t(size));
162 read_data(s.data(), size_t(size));
163 }
164 return s;
165 }
166
167 ////////////////////////////////////////////////////////////////////////////
169 ////////////////////////////////////////////////////////////////////////////
170 {
171 if (buffer_has_write_data())
172 {
173 Destructor_Logger::write("warning: an unflushed file is being destroyed");
174 try { write_buffer(); } catch (...) {}
175 }
176 }
177
178 ////////////////////////////////////////////////////////////////////////////
179 std::string Buffered_File::read_blob(Blob blob) const
180 ////////////////////////////////////////////////////////////////////////////
181 {
182 Async_Reader reader(*this, blob.get_position(), blob.get_end());
183 std::string result(size_t(blob.get_size()), 0);
184 reader.read(result.data(), result.size());
185 if (reader.is_end_of_file())
186 reading_past_end_of_file();
187 return result;
188 }
189}
size_t read(char *buffer, size_t capacity)
bool is_end_of_file() const
size_t index
Definition Buffer.h:20
virtual void copy_to(Buffered_File &destination, int64_t start, int64_t size) const
void set_position(int64_t position)
virtual bool equal_to(Buffered_File &destination, int64_t from, int64_t until) const
size_t read_data(char *data, const size_t n)
void write_string(const std::string &s)
std::string read_string()
void destructor_flush() noexcept
void write_data(const char *data, size_t n)
std::string safe_read_string(int64_t max_size)
Buffered_File(Open_Mode mode)
static void write(const char *message) noexcept
void sequential_seek(int64_t new_position)
Open_Mode
Definition Open_Mode.h:8
@ shared_write
like write_existing_or_create_new, but does not lock the file, and does not fail if locked
@ read_existing
fails if does not exist
Definition Blob.h:7