#include #include #include #include #include #include #include #include #include using namespace std; static DEBUG_KEY D_DOCUMENT ("document","Show document creation"); struct KEY{ unsigned owner; unsigned document; KEY(unsigned _owner, unsigned _document){ owner = _owner; document = _document; } KEY(const KEY &k){ owner = k.owner; document = k.document; } bool operator < (const KEY &k) const { bool ret = false; if (owner < k.owner){ ret = true; }else if (owner == k.owner){ ret = document < k.document; } return ret; } }; struct DOCUMENT { KEY key; long size; vector copies; // Who have a copy DOCUMENT(const KEY &_key, long _size) : key(_key){ size = _size; } DOCUMENT(): key(0,0){ size = 0; } }; struct PEER{ unsigned id; // A number to identify the peer long amount; // How much credit do we have, allowing us to rent space long margin; // Borrowing ? struct { long nodes; // How many nodes of information long node_size; // Total size (sum of all nodes) } us, // Nodes belonging to us them; // Nodes stored for others long offer; // How much are we willing to hold for other int nbdoc; // How many document we own map documents; // Document owned by this peer // and documents backuped by this peer PEER(int _id){ id = _id; amount = 0; margin = 0; offer = 0; us.nodes = 0; us.node_size = 0; them.nodes = 0; them.node_size = 0; nbdoc = 0; } void add_owner_document (long size){ KEY k (id,nbdoc); nbdoc++; documents[k] = DOCUMENT(k,size); } void adddocument (KEY &k, long size){ documents[k] = DOCUMENT(k,size); } long getdocument (KEY &k) const { long ret = -1; map::const_iterator it = documents.find (k); if (it != documents.end()) ret = it->second.size; return ret; } bool backup (const KEY &k, long size, int credit){ bool ret = false; if (size < offer){ amount += credit; offer -= size; documents[k] = DOCUMENT(k,size); ret = true; } return ret; } }; static int getrandom (int limit) { static int fd = -1; if (fd == -1){ fd = open ("/dev/urandom",O_RDONLY,0); if (fd == -1){ tlmp_error ("Can't open /dev/urandom (%s), aborting\n",strerror(errno)); exit (-1); } } int ret = -1; if (limit < 65536){ unsigned char buf[2]; int len = read (fd,buf,sizeof(buf)); if (len == sizeof(buf)){ unsigned val = ((unsigned)buf[0] << 8) + buf[1]; ret = val % limit; }else{ tlmp_error ("Error reading /dev/urandom, aborting\n"); exit (-1); } }else{ unsigned char buf[4]; int len = read (fd,buf,sizeof(buf)); if (len == sizeof(buf)){ unsigned val = ((unsigned)buf[0]<<24)+((unsigned)buf[1]<<16)+((unsigned)buf[2] << 8) + buf[3]; ret = val % limit; }else{ tlmp_error ("Error reading /dev/urandom, aborting\n"); exit (-1); } } return ret; } int main (int argc, char *argv[]) { glocal int ret = 0; glocal int nbpeers = 4; glocal int nbgen = 100; glocal int nbbackup = 2; glocal.ret = (argc,argv); setarg (' ',"nbbackup","How many backup we want",glocal.nbbackup,false); setarg (' ',"nbpeers","Number of peers to simulate",glocal.nbpeers,false); setarg (' ',"nbgen","Number of generation",glocal.nbgen,false); int ret = 0; vector peers; // Adding some players for (int i=0; i::iterator it = p.documents.begin(); it != p.documents.end(); it++){ if (it->first.owner == i && it->second.copies.size() < (unsigned)glocal.nbbackup){ // This document belongs to the peer and lacks backup for (unsigned b=0; b 0 && it->second.copies.size() < (unsigned)glocal.nbbackup; b++){ PEER &bp = peers[b]; if (bp.id != i){ if (bp.backup(it->first,it->second.size,1)){ it->second.copies.push_back(bp.id); p.amount--; } } } } } } } for (int i=0; i::iterator it = p.documents.begin(); it != p.documents.end(); it++){ if (it->first.owner == id){ if (it->second.copies.size() == 0){ dangerous++; }else if (it->second.copies.size() < (unsigned)glocal.nbbackup){ unsafe++; } } } printf ("%d: offer=%ld amount=%ld nbdoc = %lu unsafe=%d dangerous=%d\n",p.id,p.offer,p.amount,p.documents.size(),unsafe,dangerous); } return ret; return glocal.ret; }