#include #include #include #include #include #include #include "sys.hpp" #include "DnaStore.hpp" #include "TcpSocket.hpp" #include "NetConst.hpp" #include #define ID_FILE_NAME "ID.bin" #define DATA_FILE_NAME "DATA.bin" #define VECTOR_FILE_NAME "VECTOR.bin" #define GEN_FILE_PATTRN "gen%04d.bin" void DnaStore::load(DnaManagerData *data) { if (sys::fileExists(ID_FILE_NAME)) { sys::loadDataFromFile(ID_FILE_NAME, &data->id, sizeof(int64_t)); } else { data->id = time(nullptr); sys::saveDataToFile(ID_FILE_NAME, &data->id, sizeof(int64_t)); } if (sys::fileExists(DATA_FILE_NAME)) { const char *filename = sys::transformFilePath(DATA_FILE_NAME); FILE *file = fopen(filename, "rb"); if (file == NULL) return; fread(&data->randSeed, 1, sizeof(uint128), file); fread(&data->generation, 1, sizeof(int), file); fread(&data->showed, 1, sizeof(int), file); data->queued = data->showed; int size, tmp; fread(&size, sizeof(size), 1, file); for (int i = 0; i < size; i++) { fread(&tmp, sizeof(tmp), 1, file); if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now continue; data->liked.push_back(tmp); } fread(&size, sizeof(size), 1, file); for (int i = 0; i < size; i++) { fread(&tmp, sizeof(tmp), 1, file); if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now continue; data->disliked.push_back(tmp); } fclose(file); } else { data->randSeed = mrand::getState(data->id); data->queued = 0; data->showed = 0; data->generation = 0; } data->vector.resize(NUM_PER_GEN); if (sys::fileExists(VECTOR_FILE_NAME)) { sys::loadDataFromFile(VECTOR_FILE_NAME, data->vector.data(), sizeof(Dna) * NUM_PER_GEN); } else { for (std::size_t i = 0; i < NUM_PER_GEN; i++) { DNA::newDna(&data->vector[i], &data->randSeed); } saveVec(data); // v primeru da prvic ne gres cez celo generacijo se vec ne shrani in bo drugacen ker se bo regeneriral z drugim rand seed saveData(data); // save ce rand seed se je spremenil in v premeru user ugasne brez da like se rand seed ne shrani in se resetira v ID } } void DnaStore::saveData(DnaManagerData *data) { const char *filename = sys::transformFilePath(DATA_FILE_NAME); FILE *file = fopen(filename, "wb"); if (file == NULL) return; fwrite(&data->randSeed, 1, sizeof(uint128), file); fwrite(&data->generation, 1, sizeof(int), file); fwrite(&data->showed, 1, sizeof(int), file); int tmp; tmp = data->liked.size(); fwrite(&tmp, sizeof(tmp), 1, file); fwrite(data->liked.data(), sizeof(int) * tmp, 1, file); tmp = data->disliked.size(); fwrite(&tmp, sizeof(tmp), 1, file); fwrite(data->disliked.data(), sizeof(tmp) * tmp, 1, file); fclose(file); } void DnaStore::saveVec(DnaManagerData *data) { const char *filename = sys::transformFilePath(VECTOR_FILE_NAME); FILE *file = fopen(filename, "wb"); if (file == NULL) return; fwrite(data->vector.data(), sizeof(Dna) * NUM_PER_GEN, 1, file); fclose(file); } void DnaStore::saveGen(DnaManagerData *data) { std::vector gen; gen.resize(NUM_PER_GEN); for (std::size_t i = 0; i < NUM_PER_GEN; i++) { gen[i].hash = mrand::computeCRC32((unsigned char *)&data->vector[i], sizeof(Dna)); gen[i].liked = Liked::tbd; gen[i].index = i; } for (auto &&i : data->liked) { gen[i].liked = Liked::yes; } for (auto &&i : data->disliked) { gen[i].liked = Liked::no; } const char *fileName = TextFormat(GEN_FILE_PATTRN, data->generation); sys::saveDataToFile(fileName, gen.data(), sizeof(NetUnit) * NUM_PER_GEN); sync(); } void client(std::string prefix); void DnaStore::sync() { const char *prefix = sys::transformFilePath(""); std::string prefixs = prefix; std::thread t(client, prefixs); t.detach(); } void client(std::string prefix) { constexpr int extra_buff = 20; // len of 2**31 -> 2147483648 plus the pattern size std::string buffer; buffer.resize(prefix.size() + extra_buff); int sock = TcpSocket::connectt("petrovv.com", 8888); if (sock < 0) { // printf("Error %d", sock); return; } int ret = sprintf(buffer.data(), "%s/" ID_FILE_NAME, prefix.c_str()); buffer.data()[ret] = 0; std::ifstream idf(buffer, std::ios_base::binary); uint64_t ID = 0; idf.read((char *)&ID, sizeof(ID)); idf.close(); // printf("id: %ld\n", ID); TcpSocket::sendt(sock, &StartHeader, sizeof(StartHeader)); TcpSocket::sendt(sock, &ID, sizeof(ID)); Message message; int needed_gen = 0; while (true) { TcpSocket::recvt(sock, &message, sizeof(Message)); if (message.mess != Mess::REQ_SEND_GEN) { message.mess = Mess::RES_NO; TcpSocket::sendt(sock, &message, sizeof(Message)); break; } needed_gen = message.data; int ret = sprintf(buffer.data(), "%s/" GEN_FILE_PATTRN, prefix.c_str(), needed_gen); buffer.data()[ret] = 0; if (!std::filesystem::exists(buffer)) { message.mess = Mess::RES_NO; TcpSocket::sendt(sock, &message, sizeof(Message)); break; } std::ifstream sfile(buffer, std::ios_base::binary | std::ios_base::in); std::vector net; net.resize(NUM_PER_GEN); sfile.read((char *)net.data(), NUM_PER_GEN * sizeof(NetUnit)); message.mess = Mess::RES_OK; message.data = NUM_PER_GEN * sizeof(NetUnit); TcpSocket::sendt(sock, &message, sizeof(Message)); TcpSocket::sendt(sock, net.data(), NUM_PER_GEN * sizeof(NetUnit)); } TcpSocket::closet(sock); }