101 lines
2.5 KiB
C++
101 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_;
|
|
};
|
|
|