Joedb 9.1.4
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Server_File.cpp
Go to the documentation of this file.
2
3namespace joedb
4{
5 ////////////////////////////////////////////////////////////////////////////
6 size_t Server_File::remote_pread(char *data, size_t size, int64_t offset) const
7 ////////////////////////////////////////////////////////////////////////////
8 {
11 Server_Connection::buffer.write<int64_t>(offset);
12 Server_Connection::buffer.write<uint64_t>(size);
13
14 Channel_Lock lock(channel);
16 lock.read(Server_Connection::buffer.data, 9);
17
19 const size_t returned_size = size_t(Server_Connection::buffer.read<int64_t>());
20
21 for (size_t read = 0; read < returned_size;)
22 read += lock.read_some(data + read, returned_size - read);
23
24 return returned_size;
25 }
26
27 ////////////////////////////////////////////////////////////////////////////
28 void Server_File::write_to_body_error()
29 ////////////////////////////////////////////////////////////////////////////
30 {
31 throw Exception("Cannot write to Server_File body");
32 }
33
34 ////////////////////////////////////////////////////////////////////////////
35 void Server_File::write_checkpoint()
36 ////////////////////////////////////////////////////////////////////////////
37 {
41 head.flush();
42 }
43
44 ////////////////////////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////////////////////////
47 Server_Connection(channel),
49 tail_offset(server_checkpoint)
50 {
51 {
52 Writable_Journal journal(head);
53 }
54 write_checkpoint();
55 }
56
57 ////////////////////////////////////////////////////////////////////////////
58 int64_t Server_File::pull
59 ////////////////////////////////////////////////////////////////////////////
60 (
61 std::chrono::milliseconds wait,
62 char pull_type
63 )
64 {
65 if (tail.get_size() > 0)
66 throw Exception("Server_File: pulling with non-empty tail");
67
68 Server_Connection::pull(nullptr, wait, pull_type);
69 write_checkpoint();
70 tail_offset = server_checkpoint;
71
72 return server_checkpoint;
73 }
74
75 ////////////////////////////////////////////////////////////////////////////
77 ////////////////////////////////////////////////////////////////////////////
78 (
79 Readonly_Journal &client_journal,
80 bool content_check
81 )
82 {
83 if (&client_journal.get_file() != this)
84 throw Exception("Server_File: wrong file");
85 return server_checkpoint;
86 }
87
88 ////////////////////////////////////////////////////////////////////////////
89 int64_t Server_File::pull
90 ////////////////////////////////////////////////////////////////////////////
91 (
92 Writable_Journal &client_journal,
93 std::chrono::milliseconds wait
94 )
95 {
96 return pull(wait, 'i');
97 }
98
99 ////////////////////////////////////////////////////////////////////////////
101 ////////////////////////////////////////////////////////////////////////////
102 (
103 Writable_Journal &client_journal,
104 std::chrono::milliseconds wait
105 )
106 {
107 return pull(wait, 'l');
108 }
109
110 ////////////////////////////////////////////////////////////////////////////
112 ////////////////////////////////////////////////////////////////////////////
113 (
114 Readonly_Journal &client_journal,
115 const int64_t server_position,
116 const int64_t until_position,
117 const bool unlock_after
118 )
119 {
121 (
122 client_journal,
123 server_position,
124 until_position,
125 unlock_after
126 );
127
128 if (server_checkpoint == get_size())
129 {
130 tail_offset = server_checkpoint;
131 tail.resize(0);
132 }
133 else
134 throw Exception("Server_File could not truncate tail after push");
135
136 return server_checkpoint;
137 }
138
139 ////////////////////////////////////////////////////////////////////////////
140 size_t Server_File::pread(char *data, size_t size, int64_t offset) const
141 ////////////////////////////////////////////////////////////////////////////
142 {
144 return head.pread(data, size, offset);
145
146 if (offset < tail_offset)
147 return remote_pread(data, size, offset);
148
149 return tail.pread(data, size, offset - tail_offset);
150 }
151
152 ////////////////////////////////////////////////////////////////////////////
153 void Server_File::pwrite(const char *data, size_t size, int64_t offset)
154 ////////////////////////////////////////////////////////////////////////////
155 {
157 {
158 if (offset + size > Readonly_Journal::header_size)
159 write_to_body_error();
160 else
161 head.pwrite(data, size, offset);
162 }
163 else if (offset >= tail_offset)
164 tail.pwrite(data, size, offset - tail_offset);
165 else
166 write_to_body_error();
167 }
168
169 ////////////////////////////////////////////////////////////////////////////
170 std::string Server_File::read_blob_data(Blob blob) const
171 ////////////////////////////////////////////////////////////////////////////
172 {
173 if (blob.get_position() >= tail_offset)
174 return tail.read_blob_data(Blob{blob.get_position() - tail_offset});
175 else
176 {
177 Channel_Lock lock(channel);
178
181 Server_Connection::buffer.write<int64_t>(blob.get_position());
183
184 lock.read(Server_Connection::buffer.data, 9);
186 const int64_t size = Server_Connection::buffer.read<int64_t>();
187
188 Memory_File file;
189 file.resize(size_t(size));
190 joedb::Async_Writer writer(file, 0);
191 download(writer, lock, size);
192
193 return file.move_data();
194 }
195 }
196}
int64_t get_position() const noexcept
Definition Blob.h:28
size_t index
Definition Buffer.h:21
void write(T x)
Definition Buffer.h:24
void set_position(int64_t position)
void write(const char *data, size_t size)
void read(char *data, size_t size)
void pwrite(const char *buffer, size_t size, int64_t offset) override
void resize(size_t size)
Definition Memory_File.h:19
static constexpr int64_t checkpoint_offset
static constexpr int64_t header_size
friend class Server_File
int64_t pull(Writable_Journal *client_journal, std::chrono::milliseconds wait, char pull_type)
int64_t push_until(Readonly_Journal &client_journal, int64_t server_position, int64_t until_position, bool unlock_after) override
Push new data to the connection.
int64_t handshake(Readonly_Journal &client_journal, bool content_check) override
Called during Client construction.
int64_t lock_pull(Writable_Journal &client_journal, std::chrono::milliseconds wait) override
Fused lock_pull, executed at the start of a write transaction.
std::string read_blob_data(Blob blob) const override
size_t pread(char *data, size_t size, int64_t offset) const override
void pwrite(const char *data, size_t size, int64_t offset) override
int64_t push_until(Readonly_Journal &client_journal, int64_t server_position, int64_t until_position, bool unlock_after) override
Push new data to the connection.
Open_Mode
Definition Open_Mode.h:8
@ write_existing
fails if does not exist or locked, locks the file for writing
Definition Blob.h:7