Skip to content

Commit fff5e3f

Browse files
committed
Experimental support for chunk cache.
(with bugs)
1 parent 44e8b3c commit fff5e3f

4 files changed

Lines changed: 80 additions & 14 deletions

File tree

lib/include/client.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ namespace konstructs {
8787
void process_error(Packet *packet);
8888
void process_chunk(Packet *packet);
8989
void process_chunk_updated(Packet *packet);
90+
void cache_chunk(Vector3i pos, Packet *packet);
91+
std::string cached_chunk_path(Vector3i pos);
92+
bool is_chunk_cached(Vector3i pos);
93+
void load_cached_chunk(Vector3i pos);
9094
void recv_worker();
9195
void send_worker();
9296
bool is_empty_chunk(Vector3i pos);

lib/include/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ GLuint gen_faces(int components, int faces, GLfloat *data);
3030
void load_png_texture(const char *file_name);
3131
void load_png_texture_from_buffer(const char *in, int size);
3232
int file_exist(const char *filename);
33+
bool make_dir(const char *filename);
3334

3435
#endif

lib/src/client.cpp

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
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
}

lib/src/util.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,8 @@ int file_exist(const char *filename) {
9696
int result = stat(filename, &st);
9797
return result == 0;
9898
}
99+
100+
// TODO: Will will not work under windows, I think ...
101+
bool make_dir(const char *filename) {
102+
return (mkdir(filename, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != -1);
103+
}

0 commit comments

Comments
 (0)