M1-nw-project/dataStore.h
Théophile Bastian a31d9e29eb Dump data on RETURN ; FIX sending
Packet sending was broken: active iterators could be invalidated.
2016-11-27 12:16:56 +01:00

102 lines
2.5 KiB
C++

/***************************************************************************
* By Théophile Bastian, 2017
* M1 Network course project at ENS Cachan, Juliusz Chroboczek.
* License: WTFPL v2 <http://www.wtfpl.net/>
**************************************************************************/
#pragma once
#include <queue>
#include <unordered_map>
#include <set>
#include "data.h"
#include "nw_constants.h"
#include "protocol.h"
#include "Bytes.h"
class DataStore {
public:
DataStore(Protocol* proto);
~DataStore();
void update();
/** Performs bookkeeping actions. Sends packets. This function should
* be called often enough.
*/
void addData(Bytes pck, u32 seqno, u64 id, bool mine=false);
/** Adds a data in the data storage. If `mine` is `true`, the current
* node considers itself responsible for the data and will republish
* it when needed.
*/
ssize_t dataSize(u64 id);
/** Gets the size of the data with id `id`. Returns -1 if there is no
* such data stored.
*/
ssize_t readData(u64 id, char* buffer, size_t size);
/** Fills `buffer` with the data of the given `id`.
* If the data does not exist, returs -1; else, returns the length of
* data actually retrieved.
*/
const Bytes& operator[](u64 id) {
return data[id].data;
}
u32 getSeqno(u64 id) const { return curSeqno.at(id); }
void ids(std::vector<u64>& out);
/** Fills `out` with the IDs of the stored data. */
const std::set<u64> toFlood() const { return toFlood_; }
/** Returns a list of data IDs that should be flooded. */
void setFlooded(u64 id);
/** Marks a data as flooded */
void dump();
/** Dumps everything on STDIN */
private: //meth
void handleExpire(u64 id, u32 seqno);
void handleRepublish(u64 datId);
void handleFlood(u64 id);
void cleanData(u64 id);
private:
enum EvType {
EV_REPUBLISH, EV_EXPIRES
};
struct TimeEvent {
TimeEvent(time_t time, u32 seqno, u64 id, EvType type) :
time(time), seqno(seqno), id(id), type(type) {}
time_t time;
u32 seqno;
u64 id;
EvType type;
bool operator<(const TimeEvent& e) const {
return time > e.time; // Max-priority queue
}
};
struct Data {
Data() : data(), isMine(false) {}
Data(Bytes b) : data(b), isMine(false) {}
Data(Bytes b, bool mine) : data(b), isMine(mine) {}
Bytes data;
bool isMine;
};
std::priority_queue<TimeEvent> timeEvents;
Protocol* proto;
std::unordered_map<u64, Data> data;
std::unordered_map<u64, u32> curSeqno;
std::unordered_map<u64, time_t> recvTime;
std::set<u64> toFlood_;
};