1313#include < string.h>
1414#include < errno.h>
1515#include < sstream>
16+ #include < iostream>
17+ #include < fstream>
1618#include < algorithm>
1719#include < chrono>
1820#include < functional>
1921#include " client.h"
22+ #include " util.h"
2023
2124#define PROTOCOL_VERSION 8
2225#define MAX_RECV_SIZE 4096 *1024
@@ -124,12 +127,59 @@ namespace konstructs {
124127
125128 Vector3i position (p, q, k);
126129 received_chunk (position);
130+ cache_chunk (position, packet);
127131 const int blocks_size = packet->size - 3 * sizeof (int );
128132 auto chunk = make_shared<ChunkData>(position, pos, blocks_size, (uint8_t *)inflation_buffer);
129133 std::lock_guard<std::mutex> lock_packets (packets_mutex);
130134 chunks.push_back (chunk);
131135 }
132136
137+ /* Write a chunk to local disk cache */
138+ void Client::cache_chunk (Vector3i pos, Packet *packet) {
139+ std::string p_path = " cache/chunk/" + std::to_string (pos[0 ]);
140+ std::string q_path = p_path + " /" + std::to_string (pos[1 ]);
141+ std::string k_path = q_path + " /" + std::to_string (pos[2 ]);
142+
143+ if (!file_exist (" cache" )) make_dir (" cache" );
144+ if (!file_exist (" cache/chunk" )) make_dir (" cache/chunk" );
145+ if (!file_exist (p_path.c_str ())) make_dir (p_path.c_str ());
146+ if (!file_exist (q_path.c_str ())) make_dir (q_path.c_str ());
147+
148+ ofstream cf (k_path, ofstream::binary);
149+ cf.write (packet->buffer (),packet->size );
150+ cf.close ();
151+ }
152+
153+ std::string Client::cached_chunk_path (Vector3i pos) {
154+ stringstream cache_path;
155+ cache_path << " cache/chunk/" << pos[0 ] << " /" << pos[1 ] << " /" << pos[2 ];
156+
157+ return cache_path.str ();
158+ }
159+
160+ bool Client::is_chunk_cached (Vector3i pos) {
161+ return file_exist (cached_chunk_path (pos).c_str ());
162+ }
163+
164+ void Client::load_cached_chunk (Vector3i pos) {
165+ string path (cached_chunk_path (pos));
166+
167+ // Get size of file
168+ ifstream cf (path, ofstream::binary);
169+ cf.seekg (0 ,cf.end );
170+ long size = cf.tellg ();
171+ cf.seekg (0 );
172+
173+ // make a package
174+ auto packet = make_shared<Packet>(' C' , size);
175+
176+ // load the files content
177+ cf.read (packet->buffer (), size);
178+ cf.close ();
179+
180+ process_chunk (packet.get ());
181+ }
182+
133183 void Client::recv_worker () {
134184 std::cout<<" [Recv worker]: started" <<std::endl;
135185 while (1 ) {
@@ -508,12 +558,15 @@ namespace konstructs {
508558 for (int q = -r - 1 ; q < r; q++) {
509559 for (int k = -r - 1 ; k < r; k++) {
510560 Vector3i pos = p_chunk + Vector3i (p, q, k);
511-
512- if (is_empty_chunk (pos)) {
513- int distance = (pos - p_chunk).norm ();
514- // This checks removes edges so that we request a sphere not a cube
515- if (distance <= r) {
516- // Add chunk to queue
561+ int distance = (pos - p_chunk).norm ();
562+
563+ // This checks removes edges so that we request a sphere not a cube
564+ if (distance <= r) {
565+ if (is_empty_chunk (pos) && is_chunk_cached (pos)) {
566+ // Missing chunk, and we have the chunk cached on disk.
567+ load_cached_chunk (pos);
568+ } else if (is_empty_chunk (pos)) {
569+ // Request missing chunks with no local cache.
517570 chunks_to_fetch.push ({distance, pos});
518571 }
519572 }
@@ -532,14 +585,17 @@ namespace konstructs {
532585 for (int q = -r - 1 ; q < r; q++) {
533586 for (int k = -r - 1 ; k < r; k++) {
534587 Vector3i pos = p_chunk + Vector3i (p, q, k);
535-
536- if (is_empty_chunk (pos)) {
537- int distance = (pos - p_chunk).norm ();
538-
539- // This checks removes edges so that we request a sphere not a cube
540- // It also rejects chunks that was already previously added to the queue
541- // that is chunks within the old radius
542- if (distance <= r && distance >= old_r) {
588+ int distance = (pos - p_chunk).norm ();
589+
590+ // This checks removes edges so that we request a sphere not a cube
591+ // It also rejects chunks that was already previously added to the queue
592+ // that is chunks within the old radius
593+ if (distance <= r && distance >= old_r) {
594+ if (is_empty_chunk (pos) && is_chunk_cached (pos)) {
595+ // Missing chunk, and we have the chunk cached on disk.
596+ load_cached_chunk (pos);
597+ } else if (is_empty_chunk (pos)) {
598+ // Request missing chunks with no local cache.
543599 chunks_to_fetch.push ({distance, pos});
544600 }
545601 }
0 commit comments