#include <QCoreApplication>#include <QLatin1String>#include <QDebug>int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); QByteArray s1("Test"); QByteArray s2("Lkst"); struct diff { int startPos; int size; char *data; }; QVector <diff> diffs; int diffPos = -1; for (int i = 0; i < s1.size(); ++i) { if (s1[i] != s2[i]) { if (diffPos == -1) diffPos = i; } else { if (diffPos != -1 ) { int size = i - diffPos; diffs.append({diffPos,size,s2.data() + diffPos}); diffPos = -1; } } } //diff in last element(s) if (diffPos != -1) { int size = s1.size() - diffPos; diffs.append({diffPos,size,s2.data() + diffPos}); } //output diffs for (auto &i: diffs) { qDebug() << QByteArray(i.data,i.size); } QByteArray restored(s1); //restore for (auto &i: diffs) { restored.replace(i.startPos,i.size,i.data,i.size); } //output restore mem block from the source by diffs qDebug() << restored; return a.exec();}
C++ (Qt)diffs.append({diffPos,size,s2.data() + diffPos});
struct diff { int startPos; QByteArray data; };
#include <QCoreApplication>#include <QCoreApplication>#include <QBitArray>#include <QDebug>int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); QByteArray s1("Tksteeeeeeeeeeeeeeeeeeeeeeeeeeeeehhhhhhhhhhhhhhhhhhhhhhsdfsdfffffffffffffffffffffffff"); QByteArray s2("Testeeeeeeeeeeeeeeeeeeefeeeeeeeeehhhhhhhhhhhhhhhhhhhhhhsdfsdfffffffffffffffffffffffff"); struct diff { int startPos; int size; char *data; }; QVector <diff> diffs; constexpr int BLOCK_SIZE = 8; //nice to store in degree 2 const int dataSize = s1.size(); //count of blocks int blockCount = (dataSize % BLOCK_SIZE == 0) ? dataSize / BLOCK_SIZE : dataSize / BLOCK_SIZE + 1; QBitArray diffVector(blockCount); //std::bitset //fill vector for (int i = 0; i < blockCount; ++i) { int dataPos = i * blockCount; //in real word for perfomance need comapre in registers //for instance //warning - need unbounding check! //if (((__int64)s1[dataPos] != (__int64)s2[dataPos])) //or memcmp if (s1.mid(dataPos,BLOCK_SIZE) != s2.mid(dataPos,BLOCK_SIZE)) diffVector.setBit(i); } //optimize result vector - in this case union through the one block //does not matter if block size equal metadata size //bad idea if block size is more than metadata size //good idea if block size is less than metadata size for (int i = 2; i < diffVector.size();++i) { if (diffVector[i] && diffVector[i] == diffVector[i - 2]) diffVector.setBit(i - 1); } int diffPos = -1; //calc diffs for (int i = 0; i < diffVector.size(); ++i) { if (diffVector[i]) { if (diffPos == -1) diffPos = i * BLOCK_SIZE; } else { if (diffPos != -1) { int size = i * BLOCK_SIZE - diffPos; diffs.append({diffPos,size,s2.data() + diffPos}); diffPos = -1; } } } //diff in last element(s) if (diffPos != -1) { int size = dataSize - diffPos; diffs.append({diffPos,size,s2.data() + diffPos}); } //calc diff size int diffSize = 0; for (int i = 0; i < diffs.size(); ++i) { diffSize += diffs[i].size + 8; } //nothing to do - diff more that 70% of the source size double fillPercent = diffSize / (double)dataSize; if (fillPercent > 0.7) { return 0; } //DO SAVE return a.exec();}
struct diff { int startPos; int size; char *data; };
QBitArray diffVector(blockCount); //std::bitset
//in real word for perfomance need comapre in registers //for instance //warning - need unbounding check! //if (((__int64)s1[dataPos] != (__int64)s2[dataPos])) //or memcmp if (s1.mid(dataPos,BLOCK_SIZE) != s2.mid(dataPos,BLOCK_SIZE)) diffVector.setBit(i);
//nothing to do - diff more that 70% of the source size double fillPercent = diffSize / (double)dataSize; if (fillPercent > 0.7) { return 0;
struct CMemBlock { char * mData; UInt32 mSize;};