]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Now appears to be working. More testing needed. Refinement of the
authordrh <>
Fri, 2 May 2025 22:25:40 +0000 (22:25 +0000)
committerdrh <>
Fri, 2 May 2025 22:25:40 +0000 (22:25 +0000)
version-2 algorithm needed.

FossilOrigin-Name: cb035181d9fb5909696b8ec8f9c3eeb7a7dfb4b50e82e1d3f2d5ad150afcc0ff

manifest
manifest.uuid
tool/sqlite3_rsync.c

index d61a0efa66f49b341ea16241290563f83e5c7f85..3b78d8c88de981d9606167969d22fae7fac856cb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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.
index 4ea32c916d981f716c504465f573f80e67f06c3e..c81f190ec531538c2de7e7023b0a535e8515f283 100644 (file)
@@ -1 +1 @@
-c70330668690e7c3c55ae34137d5b2c91871432004b82b2b23a89fc3f1322a62
+cb035181d9fb5909696b8ec8f9c3eeb7a7dfb4b50e82e1d3f2d5ad150afcc0ff
index bf8a8dfb99224627e5bcb1b795da89823edfa4aa..62f751ad34b88641ab297f50429bbc0d6bd14640 100644 (file)
@@ -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");