/*************************************************************************** * By Théophile Bastian, 2017 * M1 Network course project at ENS Cachan, Juliusz Chroboczek. * License: WTFPL v2 **************************************************************************/ #include "dataStore.h" #include #include using namespace std; DataStore::DataStore(Protocol* proto) : proto(proto) {} DataStore::~DataStore() { } void DataStore::update() { while(!timeEvents.empty()) { const TimeEvent& evt = timeEvents.top(); if(evt.time > time(NULL)) // We're done for now. break; timeEvents.pop(); switch(evt.type) { case EV_REPUBLISH: handleRepublish(evt.id); break; case EV_EXPIRES: handleExpire(evt.id, evt.seqno); break; } } } void DataStore::addData(Bytes pck, u32 seqno, u64 id, bool mine) { if(curSeqno.find(id) != curSeqno.end() && curSeqno[id] >= seqno) return; data[id] = Data(pck, mine); curSeqno[id] = seqno; if(mine) { timeEvents.push(TimeEvent( time(NULL) + csts::TIME_REPUBLISH_DATA, seqno, id, EV_REPUBLISH)); } else { timeEvents.push(TimeEvent( time(NULL) + csts::TIMEOUT_DATA, seqno, id, EV_EXPIRES)); // If it is not renewed, it will expire. } recvTime[id] = time(NULL); fprintf(stderr, "[INFO] Storing data %lX (%u)\n", id, seqno); handleFlood(id); } ssize_t DataStore::dataSize(u64 id) { if(data.find(id) == data.end()) return -1; return data[id].data.size(); } ssize_t DataStore::readData(u64 id, char* buffer, size_t size) { if(data.find(id) == data.end()) return -1; ssize_t len = min((ssize_t)size, dataSize(id)); data[id].data.writeToBuffer(buffer, size); return len; } void DataStore::ids(std::vector& out) { for(auto& dat : data) out.push_back(dat.first); } void DataStore::setFlooded(u64 id) { toFlood_.erase(id); } void DataStore::handleExpire(u64 id, u32 seqno) { if(seqno < curSeqno[id]) return; // Was updated in time cleanData(id); } void DataStore::handleRepublish(u64 id) { if(data.find(id) == data.end() || !data[id].isMine) return; curSeqno[id] = time(NULL); handleFlood(id); } void DataStore::handleFlood(u64 id) { toFlood_.insert(id); } void DataStore::cleanData(u64 id) { curSeqno.erase(id); recvTime.erase(id); data.erase(id); // Deletes the Bytes as well }