PIDeque bugs fixed

git-svn-id: svn://db.shs.com.ru/pip@27 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
2015-03-16 12:17:14 +00:00
parent 7657996e98
commit e50bedc5ef
12 changed files with 198 additions and 217 deletions

View File

@@ -54,7 +54,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
PIChar ppc(0), pc(0), nc(0);
if (ind > 1) ppc = ret[ind - 2];
if (ind > 0) pc = ret[ind - 1];
if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),0)[0];
if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),1)[0];
if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
ind--;
ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
@@ -230,7 +230,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + d.first.size_s() < pfc.size_s()) nc = pfc.mid(ind + d.first.size_s(),0)[0];
if (ind + d.first.size_s() < pfc.size_s()) nc = pfc.mid(ind + d.first.size_s(),1)[0];
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
pfc.replace(ind, d.first.size_s(), d.second);
ind -= d.first.size_s() - d.second.size_s();
@@ -242,7 +242,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),0)[0];
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),1)[0];
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
PIString ret, range; bool ok(false);
range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");

View File

@@ -201,7 +201,13 @@ public:
}
return *this;
}
PIDeque<T> & reserve(size_t new_size) {if (new_size <= pid_rsize) return *this; size_t os = pid_size; alloc(new_size, true); pid_size = os; return *this;}
PIDeque<T> & reserve(size_t new_size) {
if (new_size <= pid_rsize) return *this;
size_t os = pid_size;
alloc(new_size, true);
pid_size = os;
return *this;
}
PIDeque<T> & insert(size_t index, const T & v = T()) {
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
@@ -213,8 +219,7 @@ public:
memmove(&(pid_data[index + pid_start + 1]), &(pid_data[index + pid_start]), os * sizeof(T));
}
} else {
pid_start--;
alloc(pid_size + 1, false);
alloc(pid_size + 1, false, -1);
//piCout << "insert front" << pid_size << pid_rsize << pid_start << "!<";
if (index > 0)
memmove(&(pid_data[pid_start]), &(pid_data[pid_start + 1]), index * sizeof(T));
@@ -226,20 +231,22 @@ public:
PIDeque<T> & insert(size_t index, const PIDeque<T> & other) {
if (other.isEmpty()) return *this;
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
//piCout << "insert" << dir << index << pid_size << pid_rsize << pid_start << "!<";
//piCout << this << "insert" << dir << index << pid_size << pid_rsize << pid_start << " <- " << other.size() << "!<";
if (dir) {
ssize_t os = pid_size - index;
alloc(pid_size + other.pid_size, true);
if (os > 0)
memmove(&(pid_data[index + pid_start + other.pid_size]), &(pid_data[index + pid_start]), os * sizeof(T));
} else {
pid_start -= other.pid_size;
alloc(pid_size + other.pid_size, false);
//piCout << "insert front" << pid_size << pid_rsize << pid_start << "!<";
//if (pid_start < other.pid_size) pid_start = 0;
//piCout << this << " insert offseted start ba" << pid_start << pid_size << pid_rsize;
alloc(pid_size + other.pid_size, false, -other.pid_size);
//piCout << this << " insert offseted start aa" << pid_start << pid_size << pid_rsize;
//piCout << this << " insert front" << pid_size << pid_rsize << pid_start << "!<";
if (index > 0)
memmove(&(pid_data[pid_start]), &(pid_data[pid_start + other.pid_size]), index * sizeof(T));
}
//piCout << "insert" << pid_start << index << (pid_start + ssize_t(index)) << pid_size << ">!";
//piCout << this << "insert" << pid_start << index << (pid_start + ssize_t(index)) << pid_size << ">!";
newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size);
return *this;
}
@@ -327,11 +334,11 @@ private:
elementNew(dst + i, src[i]);
}
inline T * newRaw(size_t s) {
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
//std::cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <" << std::endl;
//uchar * ret = new uchar[s * sizeof(T)];
uchar * ret = (uchar*)(malloc(s * sizeof(T)));//new uchar[];
//zeroRaw((T*)ret, s);
//cout << std::hex << " > (new 0x" << (llong)ret << ") ok]!" << endl;
//std::cout << std::hex << " > (new 0x" << (llong)ret << ") ok]!" << std::endl;
return (T*)ret;
}
/*void reallocRawTemp(size_t s) {
@@ -339,7 +346,7 @@ private:
else pid_tdata = (T*)(realloc(pid_tdata, s * sizeof(T)));
}*/
inline void deleteT(T * d, size_t sz) {
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
//std::cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << " start " << pid_start << std::hex << " 0x" << (llong)d << " ... <" << std::endl;
if ((uchar*)d != 0) {
for (size_t i = 0; i < sz; ++i)
elementDelete(d[i]);
@@ -362,7 +369,7 @@ private:
inline void elementDelete(T & from) {from.~T();}
void dealloc() {deleteRaw(pid_data);}
inline void checkMove(bool direction) {
if (pid_size >= 4 && pid_size < pid_rsize / 4) {
if (pid_size >= 4 && pid_size < pid_rsize / 6) {
/*if (direction) {
if (pid_start >= 4 && pid_start > pid_size + pid_size && pid_start > pid_rsize / 2) {
piCout << (int)this << "checkMove" << direction << pid_start << (int)pid_data << pid_rsize << pid_size;
@@ -378,16 +385,18 @@ private:
pid_start = ssize_t(pid_rsize) - pid_size - pid_size;
}
}*/
//printf("(%p) check move st=%d sz=%d rs=%d\n", this, pid_start, pid_size, pid_rsize);
if (pid_start < pid_size + pid_size || pid_start > pid_rsize - pid_size - pid_size) {
size_t ns = (pid_rsize - pid_size) / 2;
ssize_t ns = (pid_rsize - pid_size) / 2;
if (pid_start != ns) {
//printf("(%p) move %d -> %d\n", this, pid_start, ns);
memmove(pid_data + ns, pid_data + pid_start, pid_size * sizeof(T));
pid_start = ns;
}
}
}
}
inline void alloc(size_t new_size, bool direction) { // direction == true -> alloc forward
inline void alloc(size_t new_size, bool direction, ssize_t start_offset = 0) { // direction == true -> alloc forward
if (direction) {
if (pid_start + new_size <= pid_rsize) {
pid_size = new_size;
@@ -397,42 +406,46 @@ private:
pid_size = new_size;
size_t as = asize(pid_start + new_size);
if (as != pid_rsize) {
//printf("(%p) realloc %d -> %d (%p)\n", this, pid_rsize, as, pid_data);
pid_data = (T*)(realloc(pid_data, as*sizeof(T)));
pid_rsize = as;
//printf("(%p) realloc done (%p)\n", this, pid_data);
}
} else {
size_t as = asize(piMax<ssize_t>(new_size, pid_rsize) - pid_start);
//piCout << "alloc" << new_size << pid_size << pid_rsize << as << pid_start;
if (pid_start >= 0 && as <= pid_rsize) {
pid_size = new_size;
checkMove(direction);
return;
}
size_t os = pid_size;
pid_size = new_size;
size_t as;
//piCout << "INS ba" << *this;
if (pid_start + start_offset < 0)
as = asize(pid_rsize - start_offset);
else as = pid_rsize;
//printf("%X alloc %d %d\n", this, pid_rsize, start_offset);
//printf("%X alloc %d %d %d %d %d %d\n", this, new_size, pid_size, pid_rsize, as, pid_start, start_offset);
if (as > pid_rsize) {
//piCout << "alloc new size" << as;
//printf("%X alloc new size %d\n", this, as);
//cout << std::hex << " ![("<<this<<")realloc " << pid_data << " data ... <\n" << endl;
T * td = newRaw(as);
//piCout << "pid_start" << pid_start << (pid_start + ssize_t(as) - os);
ssize_t ost = pid_start, ns = 0;
if (ost < 0) {ns -= ost; ost = 0;}
pid_start += ssize_t(as) - os;
if (os > 0 && pid_data != 0) {
memcpy(td + pid_start + ns, pid_data + ost, os * sizeof(T));
ssize_t ns = pid_start + as - pid_rsize;
//printf("%X pid_start ost=%d ors=%d nst=%d nrs=%d\n", this, pid_start, pid_rsize, ns, as);
if (pid_rsize > 0 && pid_data != 0) {
//printf("%X copy from %p + %d to %p + %d %d el\n", this, pid_data, pid_start, td, ns, pid_size);
memcpy(td + ns, pid_data + pid_start, pid_size * sizeof(T));
deleteRaw(pid_data);
}
pid_data = td;
pid_rsize = as;
pid_start = ns;
//piCout << "INS aa" << *this;
}
pid_start += start_offset;
pid_size = new_size;
checkMove(direction);
}
//checkMove(direction);
//piCout << "alloc new start" << pid_start;
//printf("%X alloc new start %d\n", this, pid_start);
}
T * pid_data;
volatile size_t pid_size, pid_rsize;
volatile size_t pid_start;
volatile ssize_t pid_start;
};
#define __PIDEQUE_SIMPLE_TYPE__(T) \

View File

@@ -145,6 +145,7 @@
# pragma GCC diagnostic ignored "-Wformat"
# pragma GCC diagnostic ignored "-Wformat-extra-args"
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
# pragma GCC diagnostic ignored "-Wsign-compare"
# endif
# ifdef ANDROID
# pragma GCC diagnostic ignored "-Wunused-parameter"

View File

@@ -121,6 +121,13 @@ PIFile::PIFile(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(p
}
PIFile::PIFile(const PIFile & other) {
setPrecision(other.prec_);
setPath(other.path());
mode_ = other.mode_;
}
bool PIFile::openDevice() {
close();
PIString p = path();

View File

@@ -32,7 +32,7 @@ class PIP_EXPORT PIFile: public PIIODevice
public:
//! Constructs an empty file
PIFile();
explicit PIFile();
struct FileInfo {
FileInfo() {size = 0; id_group = id_user = 0;}
@@ -84,7 +84,9 @@ public:
};
//! Constructs a file with path "path" nad open mode "type"
PIFile(const PIString & path, DeviceMode mode = ReadWrite);
explicit PIFile(const PIString & path, DeviceMode mode = ReadWrite);
PIFile(const PIFile & other);
~PIFile() {close();}
@@ -246,7 +248,7 @@ public:
EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill);
//! Returns not opened temporary file with open mode "mode"
//! Returns opened temporary file with open mode "mode"
static PIFile openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite) {return PIFile(PIString(tmpnam(0)), mode);}
//! Returns if file with path "path" does exists

View File

@@ -19,7 +19,7 @@
#include "pipeer.h"
#define _PIPEER_MSG_SIZE 8192
#define _PIPEER_MSG_SIZE 8000
#define _PIPEER_MULTICAST_TTL 4
#define _PIPEER_MULTICAST_IP "232.13.3.12"
#define _PIPEER_LOOPBACK_PORT_S 13313
@@ -211,7 +211,7 @@ void PIPeer::destroyMBcasts() {
PIPeer::PeerInfo * PIPeer::quickestPeer(const PIString & to) {
if (!addresses_map.contains(to)) return 0;
if (!peers_map.contains(to)) return 0;
//piCout << "*** search quickest peer" << to;
PIVector<PeerInfo * > tp = addresses_map[to];
PeerInfo * dp = 0;
@@ -229,6 +229,7 @@ PIPeer::PeerInfo * PIPeer::quickestPeer(const PIString & to) {
bool PIPeer::send(const PIString & to, const void * data, int size) {
PIMutexLocker mlocker(peers_mutex);
PeerInfo * dp = quickestPeer(to);
if (dp == 0) {
//piCoutObj << "Can`t find peer \"" << to << "\"!";
@@ -258,13 +259,13 @@ bool PIPeer::dataRead(uchar * readed, int size) {
PIString from, to;
ba >> type;
PIMutexLocker locker(eth_mutex);
PIMutexLocker plocker(peers_mutex);
//piCout << "[PIPeer \"" + name_ + "\"] Received packet" << type;
if (type == 5) { // ping request
PIString addr;
PISystemTime time;
ba >> to >> from >> addr >> time;
piCout << "ping request" << to << from << addr;
//piCout << "ping request" << to << from << addr;
PIMutexLocker plocker(peers_mutex);
if (from == self_info.name) { // send ping back
const PeerInfo * pi = getPeerByName(to);
if (pi) {
@@ -284,7 +285,8 @@ bool PIPeer::dataRead(uchar * readed, int size) {
PIString addr;
PISystemTime time, ptime, ctime = PISystemTime::current(true);
ba >> to >> from >> addr >> time;
piCout << "ping reply" << to << from << addr;
//piCout << "ping reply" << to << from << addr;
PIMutexLocker plocker(peers_mutex);
if (to == self_info.name) { // ping echo
piForeach (PeerInfo & p, peers) {
if (!p.isNeighbour()) continue;
@@ -297,7 +299,7 @@ bool PIPeer::dataRead(uchar * readed, int size) {
a.wait_ping = false;
if (a.ping < 0) a.ping = ptime.toMilliseconds();
else a.ping = 0.6 * a.ping + 0.4 * ptime.toMilliseconds();
piCout << "*** ping echo" << p.name << a.address << a.ping;
//piCout << "*** ping echo" << p.name << a.address << a.ping;
return true;
}
}
@@ -318,8 +320,12 @@ bool PIPeer::dataRead(uchar * readed, int size) {
dataReceivedEvent(from, ba);
return true;
}
peers_mutex.lock();
PeerInfo * fp = const_cast<PeerInfo * >(getPeerByName(from));
if (fp == 0) return true;
if (fp == 0) {
peers_mutex.unlock();
return true;
}
PeerData & pd(fp->_data);
if (cmsg == 0) {
//piCout << "[PIPeer \"" + name_ + "\"] Packet clear" << rec_size;
@@ -328,13 +334,17 @@ bool PIPeer::dataRead(uchar * readed, int size) {
}
//piCout << "[PIPeer \"" + name_ + "\"] Packet add" << cmsg << ba.size_s();
pd.addData(ba);
if (pd.isFullReceived()) {
dataReceived(from, pd.data);
dataReceivedEvent(from, pd.data);
bool frec = pd.isFullReceived();
PIByteArray rba(pd.data);
peers_mutex.unlock();
if (frec) {
dataReceived(from, rba);
dataReceivedEvent(from, rba);
//piCout << "[PIPeer \"" + name_ + "\"] Packet received" << pd.data.size_s();
}
return true;
}
PIMutexLocker plocker(peers_mutex);
PeerInfo * dp = quickestPeer(to);
if (dp == 0) {
//piCoutObj << "Can`t find peer \"" << to << "\"!";
@@ -379,8 +389,8 @@ bool PIPeer::mbcastRead(uchar * data, int size) {
self_info.addNeighbour(pi.name);
}
peers << pi;
findNearestAddresses();
piCoutObj << "new peer \"" << pi.name << "\"" << " dist " << pi.dist;
buildMap();
//piCoutObj << "new peer \"" << pi.name << "\"" << " dist " << pi.dist;
pi.dist++;
sendSelfInfo();
sendPeerInfo(pi);
@@ -398,11 +408,11 @@ bool PIPeer::mbcastRead(uchar * data, int size) {
dist = rpi->dist;
addToRemoved(*rpi);
removePeer(pi.name);
piCoutObj << "remove peer \"" << pi.name << "\"";
//piCoutObj << "remove peer \"" << pi.name << "\"";
if (dist == 0)
self_info.removeNeighbour(pi.name);
sendPeerRemove(pi.name);
findNearestAddresses();
buildMap();
peerDisconnected(pi.name);
peerDisconnectedEvent(pi.name);
//piCout << "remove peer packet ok";
@@ -464,7 +474,7 @@ bool PIPeer::mbcastRead(uchar * data, int size) {
//piCout << i.name << i.neighbours;
}
if (ch)
findNearestAddresses();
buildMap();
peers_mutex.unlock();
//piCoutObj << "after sync " << peers.size_s() << " peers";
break;
@@ -542,7 +552,7 @@ void PIPeer::pingNeighbours() {
a.wait_ping = true;
sba = ba;
sba << p.name << a.address << PISystemTime::current(true);
piCout << "ping" << p.name << a.address << a.last_ping;
//piCout << "ping" << p.name << a.address << a.last_ping;
if (eth_send.send(a.address, sba))
diag_s.sended(sba.size_s());
}
@@ -556,11 +566,11 @@ void PIPeer::syncPeers() {
PIString pn;
bool change = false;
peers_mutex.lock();
for (uint i = 0; i < peers.size(); ++i) {
for (int i = 0; i < peers.size_s(); ++i) {
PeerInfo & cp(peers[i]);
if (cp.sync > 3) {
pn = cp.name;
piCoutObj << "sync: remove " << pn;
//piCoutObj << "sync: remove " << pn;
addToRemoved(cp);
peers.remove(i);
sendPeerRemove(pn);
@@ -580,7 +590,7 @@ void PIPeer::syncPeers() {
cp.was_update = false;
}
pingNeighbours();
if (change) findNearestAddresses();
if (change) buildMap();
self_info.cnt++;
self_info.time = PISystemTime::current();
PIByteArray ba;
@@ -590,9 +600,13 @@ void PIPeer::syncPeers() {
}
void PIPeer::findNearestAddresses() {
//piCout << "[PIPeer \"" + name_ + "\"] findNearestAddresses";
void PIPeer::buildMap() {
//piCout << "[PIPeer \"" + name_ + "\"] buildMap";
peers_map.clear();
addresses_map.clear();
piForeach (PeerInfo & i, peers)
peers_map[i.name] = &i;
return;
int max_dist = -1;
PIMap<PIString, PeerInfo * > peers_;
self_info._nuses.resize(self_info.neighbours.size());

View File

@@ -115,7 +115,7 @@ public:
const PIVector<PIPeer::PeerInfo> & allPeers() const {return peers;}
bool isPeerExists(const PIString & name) const {return getPeerByName(name) != 0;}
const PeerInfo * getPeerByName(const PIString & name) const {piForeachC (PeerInfo & i, peers) if (i.name == name) return &i; return 0;}
const PeerInfo * getPeerByName(const PIString & name) const {return peers_map.value(name, 0);}
const PeerInfo & selfInfo() const {return self_info;}
const PIMap<PIString, PIVector<PeerInfo * > > & _peerMap() const {return addresses_map;}
@@ -145,7 +145,7 @@ private:
void sendSelfInfo() {sendPeerInfo(self_info);}
void sendSelfRemove() {sendPeerRemove(self_info.name);}
void syncPeers();
void findNearestAddresses();
void buildMap();
void initEths(PIStringList al);
void initMBcasts(PIStringList al);
void destroyMBcasts();
@@ -170,6 +170,7 @@ private:
PeerInfo self_info;
PIVector<PeerInfo> peers;
PIMap<PIString, PeerInfo * > peers_map;
PIMap<PIString, PIVector<PeerInfo * > > addresses_map; // map {"to" = list of nearest peers}
PIMap<PIString, PIPair<int, PISystemTime> > removed;
PIDiagnostics diag_s, diag_d;

View File

@@ -365,9 +365,18 @@ PITimer::PITimer(PITimer::TimerImplementation ti): PIObject() {
PITimer::PITimer(TimerEvent slot, void * data, PITimer::TimerImplementation ti): PIObject() {
piMonitor.timers++;
imp_mode = ti;
initFirst();
data_t = data;
ret_func = slot;
initFirst();
}
PITimer::PITimer(const PITimer & other): PIObject() {
piMonitor.timers++;
imp_mode = other.imp_mode;
data_t = other.data_t;
ret_func = other.ret_func;
initFirst();
}

View File

@@ -151,6 +151,8 @@ public:
//! \brief Constructs timer with "slot" slot, "data" data and "ti" implementation
explicit PITimer(TimerEvent slot, void * data = 0, TimerImplementation ti = Thread);
PITimer(const PITimer & other);
virtual ~PITimer();