diff options
-rw-r--r-- | manifest | 12 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | tool/sqlite3_rsync.c | 99 |
3 files changed, 66 insertions, 47 deletions
@@ -1,5 +1,5 @@ -C Bug\sfixes.\s\sAdded\snew\sdebugging\sfeatures\sto\sbetter\svisualize\sthe\nprotocol. -D 2025-05-02T18:32:46.784 +C Now\sappears\sto\sbe\sworking.\s\sMore\stesting\sneeded.\s\sRefinement\sof\sthe\nversion-2\salgorithm\sneeded. +D 2025-05-02T22:25:40.184 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -2189,7 +2189,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 07e18a1d8cc3f6b3a4a1f3528e63c9b29a5c8a7bca0b8d394b231da464ce1247 F tool/sqldiff.c 134be7866be19f8beb32043d5aea5657f01aaeae2df8d33d758ff722c78666b9 F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69ae87b56a1a43b -F tool/sqlite3_rsync.c b786fe6316fe7ab4dc9c9f4f81c202f1baac66a49ef7a198121472f684977ce9 +F tool/sqlite3_rsync.c 7f61ac7b58fe7d0d5a6abbd1570c75bce9c160fc0d5b1b679b2213d03f047b27 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 266b4b8f0104bd4b1cff87ed78b0223006bf661a9650294a2b330d50c7ee8a0c -R b7a2f023d4216a23fb40df2130b3b81c +P c70330668690e7c3c55ae34137d5b2c91871432004b82b2b23a89fc3f1322a62 +R 68278fe558d911d1ca48d9ecb46d934b U drh -Z 82daa27df570baf781be22c975da80d8 +Z 92a9f6cb386b9d8c6c4ee41cda50ebec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4ea32c916..c81f190ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c70330668690e7c3c55ae34137d5b2c91871432004b82b2b23a89fc3f1322a62 +cb035181d9fb5909696b8ec8f9c3eeb7a7dfb4b50e82e1d3f2d5ad150afcc0ff diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index bf8a8dfb9..62f751ad3 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -1298,12 +1298,12 @@ static void originSide(SQLiteRsync *p){ unsigned int nPage = 0; unsigned int iHash = 1; /* Pgno for next hash to receive */ unsigned int nHash = 1; /* Number of pages per hash received */ + unsigned int mxHash = 0; /* Maximum hash value received */ unsigned int lockBytePage = 0; unsigned int szPg = 0; sqlite3_stmt *pCkHash = 0; /* Verify hash on a single page */ sqlite3_stmt *pCkHashN = 0; /* Verify a multi-page hash */ sqlite3_stmt *pInsHash = 0; /* Record a bad hash */ - unsigned int nMulti = 0; /* Multi-page hashes not matched */ char buf[200]; p->isReplica = 0; @@ -1387,38 +1387,37 @@ static void originSide(SQLiteRsync *p){ break; } case REPLICA_HASH: { + int bMatch = 0; if( pCkHash==0 ){ runSql(p, "CREATE TEMP TABLE badHash(" " pgno INTEGER PRIMARY KEY," " sz INT)"); pCkHash = prepareStmt(p, - "SELECT pgno FROM sqlite_dbpage('main')" - " WHERE pgno=?1 AND hash(data)!=?3" + "SELECT hash(data)==?3 FROM sqlite_dbpage('main')" + " WHERE pgno=?1" ); if( pCkHash==0 ) break; pInsHash = prepareStmt(p, "INSERT INTO badHash VALUES(?1,?2)"); if( pInsHash==0 ) break; } p->nHashSent++; - if( p->zDebugFile ){ - debugMessage(p, "<- REPLICA_HASH %u %u\n", iHash, nHash); - } + readBytes(p, 20, buf); if( nHash>1 ){ if( pCkHashN==0 ){ pCkHashN = prepareStmt(p, - "WITH a1(pgno) AS " - "(VALUES(?1) UNION ALL SELECT pgno+1 FROM a1 WHERE pgno<?2)" - "SELECT count(*) FROM a1 CROSS JOIN sqlite_dbpage('main')" - " USING(pgno)" - " HAVING agghash(hash(data))!=?3"); + "WITH c(n) AS " + " (VALUES(?1) UNION ALL SELECT n+1 FROM c WHERE n<?2)" + "SELECT agghash(hash(data))==?3" + " FROM c CROSS JOIN sqlite_dbpage('main') ON pgno=n" + ); if( pCkHashN==0 ) break; } sqlite3_bind_int64(pCkHashN, 1, iHash); - sqlite3_bind_int64(pCkHashN, 2, iHash + nHash); - readBytes(p, 20, buf); - sqlite3_bind_blob(pCkHash, 3, buf, 20, SQLITE_STATIC); + sqlite3_bind_int64(pCkHashN, 2, iHash + nHash - 1); + sqlite3_bind_blob(pCkHashN, 3, buf, 20, SQLITE_STATIC); + rc = sqlite3_step(pCkHashN); if( rc==SQLITE_ROW ){ - nMulti++; + bMatch = sqlite3_column_int(pCkHashN,0); }else if( rc==SQLITE_ERROR ){ reportError(p, "SQL statement [%s] failed: %s", sqlite3_sql(pCkHashN), sqlite3_errmsg(p->db)); @@ -1426,16 +1425,24 @@ static void originSide(SQLiteRsync *p){ sqlite3_reset(pCkHashN); }else{ sqlite3_bind_int64(pCkHash, 1, iHash); - readBytes(p, 20, buf); sqlite3_bind_blob(pCkHash, 3, buf, 20, SQLITE_STATIC); rc = sqlite3_step(pCkHash); if( rc==SQLITE_ERROR ){ reportError(p, "SQL statement [%s] failed: %s", sqlite3_sql(pCkHash), sqlite3_errmsg(p->db)); + }else if( rc==SQLITE_ROW && sqlite3_column_int(pCkHash,0) ){ + bMatch = 1; } sqlite3_reset(pCkHash); } - if( rc==SQLITE_ROW ){ + if( p->zDebugFile ){ + debugMessage(p, "<- REPLICA_HASH %u %u %s %08x...\n", + iHash, nHash, + bMatch ? "match" : "fail", + *(unsigned int*)buf + ); + } + if( !bMatch ){ sqlite3_bind_int64(pInsHash, 1, iHash); sqlite3_bind_int64(pInsHash, 2, nHash); rc = sqlite3_step(pInsHash); @@ -1445,30 +1452,32 @@ static void originSide(SQLiteRsync *p){ } sqlite3_reset(pInsHash); } + if( iHash+nHash>mxHash ) mxHash = iHash+nHash; iHash += nHash; break; } case REPLICA_READY: { + int nMulti = 0; + sqlite3_stmt *pStmt; if( p->zDebugFile ){ debugMessage(p, "<- REPLICA_READY\n"); } - if( nMulti>0 ){ - sqlite3_stmt *pStmt; - pStmt = prepareStmt(p,"SELECT pgno, sz FROM badHash WHERE sz>1"); - if( pStmt==0 ) break; - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - unsigned int pgno = (unsigned int)sqlite3_column_int64(pStmt,0); - unsigned int cnt = (unsigned int)sqlite3_column_int64(pStmt,1); - writeByte(p, ORIGIN_DETAIL); - writeUint32(p, pgno); - writeUint32(p, cnt); - if( p->zDebugFile ){ - debugMessage(p, "-> ORIGIN_DETAIL %u %u\n", pgno, cnt); - } + pStmt = prepareStmt(p,"SELECT pgno, sz FROM badHash WHERE sz>1"); + if( pStmt==0 ) break; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + unsigned int pgno = (unsigned int)sqlite3_column_int64(pStmt,0); + unsigned int cnt = (unsigned int)sqlite3_column_int64(pStmt,1); + writeByte(p, ORIGIN_DETAIL); + writeUint32(p, pgno); + writeUint32(p, cnt); + nMulti++; + if( p->zDebugFile ){ + debugMessage(p, "-> ORIGIN_DETAIL %u %u\n", pgno, cnt); } - sqlite3_finalize(pStmt); + } + sqlite3_finalize(pStmt); + if( nMulti ){ runSql(p, "DELETE FROM badHash WHERE sz>1"); - nMulti = 0; writeByte(p, ORIGIN_READY); if( p->zDebugFile ) debugMessage(p, "-> ORIGIN_READY\n"); }else{ @@ -1478,11 +1487,11 @@ static void originSide(SQLiteRsync *p){ sqlite3_finalize(pInsHash); pCkHash = 0; pInsHash = 0; - if( iHash+1<p->nPage ){ + if( mxHash<p->nPage ){ runSql(p, "WITH RECURSIVE c(n) AS" " (VALUES(%d) UNION ALL SELECT n+1 FROM c WHERE n<%d)" " INSERT INTO badHash SELECT n, 1 FROM c", - iHash+1, p->nPage); + mxHash, p->nPage); } runSql(p, "DELETE FROM badHash WHERE pgno=%d", lockBytePage); pStmt = prepareStmt(p, @@ -1551,7 +1560,7 @@ static void sendHashMessages( "SELECT if(npg==1," " (SELECT hash(data) FROM sqlite_dbpage('replica') WHERE pgno=fpg)," " (WITH RECURSIVE c(n) AS" - " (SELECT fpg UNION ALL SELECT n+1 FROM c WHERE n<fpg+npg)" + " (SELECT fpg UNION ALL SELECT n+1 FROM c WHERE n<fpg+npg-1)" " SELECT agghash(hash(data))" " FROM c CROSS JOIN sqlite_dbpage('replica') ON pgno=n)) AS hash," " fpg," @@ -1570,9 +1579,18 @@ static void sendHashMessages( debugMessage(p, "-> REPLICA_CONFIG %u %u\n", pgno, npg); } } - writeByte(p, REPLICA_HASH); - writeBytes(p, 20, a); - if( p->zDebugFile ) debugMessage(p, "-> REPLICA_HASH %u\n", iHash); + if( a==0 ){ + if( p->zDebugFile ){ + debugMessage(p, "# Oops: No hash for %u %u\n", pgno, npg); + } + }else{ + writeByte(p, REPLICA_HASH); + writeBytes(p, 20, a); + if( p->zDebugFile ){ + debugMessage(p, "-> REPLICA_HASH %u %u (%08x...)\n", + pgno, npg, *(unsigned int*)a); + } + } p->nHashSent++; iHash = pgno + npg; nHash = npg; @@ -1770,14 +1788,15 @@ static void replicaSide(SQLiteRsync *p){ "replica is %d bytes", szOPage, szRPage); break; } - if( p->iProtocol<2 ){ + if( p->iProtocol<2 || nRPage<=100 ){ runSql(p, "WITH RECURSIVE c(n) AS" "(VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<%d)" "INSERT INTO sendHash(fpg, npg) SELECT n, 1 FROM c", nRPage); }else{ - subdivideHashRange(p, 1, nRPage); + runSql(p,"INSERT INTO sendHash VALUES(1,1)"); + subdivideHashRange(p, 2, nRPage); } sendHashMessages(p, 1, 1); runSql(p, "PRAGMA writable_schema=ON"); |