Fossil SCM
Optimize sync of long cluster chains by sending all cluster artifacts on the third client/server round-trip.
Commit
637fcef83023bad32ecf73db8cd9e55a122649e1373684d7aef0263b202541fc
Parent
9953b169766f74f…
1 file changed
+55
-2
+55
-2
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1041,10 +1041,43 @@ | ||
| 1041 | 1041 | } |
| 1042 | 1042 | db_finalize(&q); |
| 1043 | 1043 | if( cnt==0 ) pXfer->resync = 0; |
| 1044 | 1044 | return cnt; |
| 1045 | 1045 | } |
| 1046 | + | |
| 1047 | +/* | |
| 1048 | +** Send an igot message for every cluster artifact that is not a phantom, | |
| 1049 | +** is not shunned, is not private, and that is not in the UNCLUSTERED table. | |
| 1050 | +** Return the number of cards sent. | |
| 1051 | +*/ | |
| 1052 | +static int send_all_clusters(Xfer *pXfer){ | |
| 1053 | + Stmt q; | |
| 1054 | + int cnt = 0; | |
| 1055 | + const char *zExtra; | |
| 1056 | + if( db_table_exists("temp","onremote") ){ | |
| 1057 | + zExtra = " AND NOT EXISTS(SELECT 1 FROM onremote WHERE rid=blob.rid)"; | |
| 1058 | + }else{ | |
| 1059 | + zExtra = ""; | |
| 1060 | + } | |
| 1061 | + db_prepare(&q, | |
| 1062 | + "SELECT uuid" | |
| 1063 | + " FROM tagxref JOIN blob ON tagxref.rid=blob.rid AND tagxref.tagid=%d" | |
| 1064 | + " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" | |
| 1065 | + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)" | |
| 1066 | + " AND NOT EXISTS(SELECT 1 FROM unclustered WHERE rid=blob.rid)" | |
| 1067 | + " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)%s", | |
| 1068 | + TAG_CLUSTER, zExtra /*safe-for-%s*/ | |
| 1069 | + ); | |
| 1070 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 1071 | + if( cnt==0 ) blob_appendf(pXfer->pOut, "# sending-clusters\n"); | |
| 1072 | + blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0)); | |
| 1073 | + cnt++; | |
| 1074 | + } | |
| 1075 | + db_finalize(&q); | |
| 1076 | + if( cnt ) blob_appendf(pXfer->pOut, "# end-of-clusters\n"); | |
| 1077 | + return cnt; | |
| 1078 | +} | |
| 1046 | 1079 | |
| 1047 | 1080 | /* |
| 1048 | 1081 | ** Send an igot message for every artifact. |
| 1049 | 1082 | */ |
| 1050 | 1083 | static void send_all(Xfer *pXfer){ |
| @@ -1781,10 +1814,19 @@ | ||
| 1781 | 1814 | ** The client sends this message to the server to ask the server |
| 1782 | 1815 | ** to tell it about alternative repositories in the reply. |
| 1783 | 1816 | */ |
| 1784 | 1817 | if( blob_eq(&xfer.aToken[1], "req-links") ){ |
| 1785 | 1818 | bSendLinks = 1; |
| 1819 | + }else | |
| 1820 | + | |
| 1821 | + /* pragma req-clusters | |
| 1822 | + ** | |
| 1823 | + ** This pragma requests that the server send igot cards for every | |
| 1824 | + ** cluster artifact that it knows about. | |
| 1825 | + */ | |
| 1826 | + if( blob_eq(&xfer.aToken[1], "req-clusters") ){ | |
| 1827 | + send_all_clusters(&xfer); | |
| 1786 | 1828 | } |
| 1787 | 1829 | |
| 1788 | 1830 | }else |
| 1789 | 1831 | |
| 1790 | 1832 | /* Unknown message |
| @@ -1981,11 +2023,11 @@ | ||
| 1981 | 2023 | int nCardSent = 0; /* Number of cards sent */ |
| 1982 | 2024 | int nCardRcvd = 0; /* Number of cards received */ |
| 1983 | 2025 | int nCycle = 0; /* Number of round trips to the server */ |
| 1984 | 2026 | int size; /* Size of a config value or uvfile */ |
| 1985 | 2027 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 1986 | - int nFileRecv; /* Number of files received */ | |
| 2028 | + int nFileRecv = 0; /* Number of files received */ | |
| 1987 | 2029 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 1988 | 2030 | const char *zCookie; /* Server cookie */ |
| 1989 | 2031 | i64 nUncSent, nUncRcvd; /* Bytes sent and received (before compression) */ |
| 1990 | 2032 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| 1991 | 2033 | int cloneSeqno = 1; /* Sequence number for clones */ |
| @@ -2007,10 +2049,11 @@ | ||
| 2007 | 2049 | int uvHashSent = 0; /* The "pragma uv-hash" message has been sent */ |
| 2008 | 2050 | int uvDoPush = 0; /* Generate uvfile messages to send to server */ |
| 2009 | 2051 | int uvPullOnly = 0; /* 1: pull-only. 2: pull-only warning issued */ |
| 2010 | 2052 | int nUvGimmeSent = 0; /* Number of uvgimme cards sent on this cycle */ |
| 2011 | 2053 | int nUvFileRcvd = 0; /* Number of uvfile cards received on this cycle */ |
| 2054 | + int nGimmeRcvd = 0; /* Number of gimme cards recevied on the prev cycle */ | |
| 2012 | 2055 | sqlite3_int64 mtime; /* Modification time on a UV file */ |
| 2013 | 2056 | int autopushFailed = 0; /* Autopush following commit failed if true */ |
| 2014 | 2057 | const char *zCkinLock; /* Name of check-in to lock. NULL for none */ |
| 2015 | 2058 | const char *zClientId; /* A unique identifier for this check-out */ |
| 2016 | 2059 | unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */ |
| @@ -2181,15 +2224,21 @@ | ||
| 2181 | 2224 | */ |
| 2182 | 2225 | if( (syncFlags & SYNC_PULL)!=0 |
| 2183 | 2226 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 2184 | 2227 | ){ |
| 2185 | 2228 | request_phantoms(&xfer, mxPhantomReq); |
| 2229 | + if( xfer.nGimmeSent>0 && nCycle==2 && (syncFlags & SYNC_PULL)!=0 ){ | |
| 2230 | + blob_appendf(&send, "pragma req-clusters\n"); | |
| 2231 | + } | |
| 2186 | 2232 | } |
| 2187 | 2233 | if( syncFlags & SYNC_PUSH ){ |
| 2188 | 2234 | send_unsent(&xfer); |
| 2189 | 2235 | nCardSent += send_unclustered(&xfer); |
| 2190 | 2236 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 2237 | + if( nGimmeRcvd>0 && nCycle==2 ){ | |
| 2238 | + send_all_clusters(&xfer); | |
| 2239 | + } | |
| 2191 | 2240 | } |
| 2192 | 2241 | |
| 2193 | 2242 | /* Client sends configuration parameter requests. On a clone, delay sending |
| 2194 | 2243 | ** this until the second cycle since the login card might fail on |
| 2195 | 2244 | ** the first cycle. |
| @@ -2369,10 +2418,11 @@ | ||
| 2369 | 2418 | nCardSent++; |
| 2370 | 2419 | } |
| 2371 | 2420 | go = 0; |
| 2372 | 2421 | nUvGimmeSent = 0; |
| 2373 | 2422 | nUvFileRcvd = 0; |
| 2423 | + nGimmeRcvd = 0; | |
| 2374 | 2424 | nPriorArtifact = nArtifactRcvd; |
| 2375 | 2425 | |
| 2376 | 2426 | /* Process the reply that came back from the server */ |
| 2377 | 2427 | while( blob_line(&recv, &xfer.line) ){ |
| 2378 | 2428 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| @@ -2449,11 +2499,14 @@ | ||
| 2449 | 2499 | && blob_is_hname(&xfer.aToken[1]) |
| 2450 | 2500 | ){ |
| 2451 | 2501 | remote_unk(&xfer.aToken[1]); |
| 2452 | 2502 | if( syncFlags & SYNC_PUSH ){ |
| 2453 | 2503 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 2454 | - if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); | |
| 2504 | + if( rid ){ | |
| 2505 | + send_file(&xfer, rid, &xfer.aToken[1], 0); | |
| 2506 | + nGimmeRcvd++; | |
| 2507 | + } | |
| 2455 | 2508 | } |
| 2456 | 2509 | }else |
| 2457 | 2510 | |
| 2458 | 2511 | /* igot HASH ?PRIVATEFLAG? |
| 2459 | 2512 | ** |
| 2460 | 2513 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1041,10 +1041,43 @@ | |
| 1041 | } |
| 1042 | db_finalize(&q); |
| 1043 | if( cnt==0 ) pXfer->resync = 0; |
| 1044 | return cnt; |
| 1045 | } |
| 1046 | |
| 1047 | /* |
| 1048 | ** Send an igot message for every artifact. |
| 1049 | */ |
| 1050 | static void send_all(Xfer *pXfer){ |
| @@ -1781,10 +1814,19 @@ | |
| 1781 | ** The client sends this message to the server to ask the server |
| 1782 | ** to tell it about alternative repositories in the reply. |
| 1783 | */ |
| 1784 | if( blob_eq(&xfer.aToken[1], "req-links") ){ |
| 1785 | bSendLinks = 1; |
| 1786 | } |
| 1787 | |
| 1788 | }else |
| 1789 | |
| 1790 | /* Unknown message |
| @@ -1981,11 +2023,11 @@ | |
| 1981 | int nCardSent = 0; /* Number of cards sent */ |
| 1982 | int nCardRcvd = 0; /* Number of cards received */ |
| 1983 | int nCycle = 0; /* Number of round trips to the server */ |
| 1984 | int size; /* Size of a config value or uvfile */ |
| 1985 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 1986 | int nFileRecv; /* Number of files received */ |
| 1987 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 1988 | const char *zCookie; /* Server cookie */ |
| 1989 | i64 nUncSent, nUncRcvd; /* Bytes sent and received (before compression) */ |
| 1990 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| 1991 | int cloneSeqno = 1; /* Sequence number for clones */ |
| @@ -2007,10 +2049,11 @@ | |
| 2007 | int uvHashSent = 0; /* The "pragma uv-hash" message has been sent */ |
| 2008 | int uvDoPush = 0; /* Generate uvfile messages to send to server */ |
| 2009 | int uvPullOnly = 0; /* 1: pull-only. 2: pull-only warning issued */ |
| 2010 | int nUvGimmeSent = 0; /* Number of uvgimme cards sent on this cycle */ |
| 2011 | int nUvFileRcvd = 0; /* Number of uvfile cards received on this cycle */ |
| 2012 | sqlite3_int64 mtime; /* Modification time on a UV file */ |
| 2013 | int autopushFailed = 0; /* Autopush following commit failed if true */ |
| 2014 | const char *zCkinLock; /* Name of check-in to lock. NULL for none */ |
| 2015 | const char *zClientId; /* A unique identifier for this check-out */ |
| 2016 | unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */ |
| @@ -2181,15 +2224,21 @@ | |
| 2181 | */ |
| 2182 | if( (syncFlags & SYNC_PULL)!=0 |
| 2183 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 2184 | ){ |
| 2185 | request_phantoms(&xfer, mxPhantomReq); |
| 2186 | } |
| 2187 | if( syncFlags & SYNC_PUSH ){ |
| 2188 | send_unsent(&xfer); |
| 2189 | nCardSent += send_unclustered(&xfer); |
| 2190 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 2191 | } |
| 2192 | |
| 2193 | /* Client sends configuration parameter requests. On a clone, delay sending |
| 2194 | ** this until the second cycle since the login card might fail on |
| 2195 | ** the first cycle. |
| @@ -2369,10 +2418,11 @@ | |
| 2369 | nCardSent++; |
| 2370 | } |
| 2371 | go = 0; |
| 2372 | nUvGimmeSent = 0; |
| 2373 | nUvFileRcvd = 0; |
| 2374 | nPriorArtifact = nArtifactRcvd; |
| 2375 | |
| 2376 | /* Process the reply that came back from the server */ |
| 2377 | while( blob_line(&recv, &xfer.line) ){ |
| 2378 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| @@ -2449,11 +2499,14 @@ | |
| 2449 | && blob_is_hname(&xfer.aToken[1]) |
| 2450 | ){ |
| 2451 | remote_unk(&xfer.aToken[1]); |
| 2452 | if( syncFlags & SYNC_PUSH ){ |
| 2453 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 2454 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 2455 | } |
| 2456 | }else |
| 2457 | |
| 2458 | /* igot HASH ?PRIVATEFLAG? |
| 2459 | ** |
| 2460 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1041,10 +1041,43 @@ | |
| 1041 | } |
| 1042 | db_finalize(&q); |
| 1043 | if( cnt==0 ) pXfer->resync = 0; |
| 1044 | return cnt; |
| 1045 | } |
| 1046 | |
| 1047 | /* |
| 1048 | ** Send an igot message for every cluster artifact that is not a phantom, |
| 1049 | ** is not shunned, is not private, and that is not in the UNCLUSTERED table. |
| 1050 | ** Return the number of cards sent. |
| 1051 | */ |
| 1052 | static int send_all_clusters(Xfer *pXfer){ |
| 1053 | Stmt q; |
| 1054 | int cnt = 0; |
| 1055 | const char *zExtra; |
| 1056 | if( db_table_exists("temp","onremote") ){ |
| 1057 | zExtra = " AND NOT EXISTS(SELECT 1 FROM onremote WHERE rid=blob.rid)"; |
| 1058 | }else{ |
| 1059 | zExtra = ""; |
| 1060 | } |
| 1061 | db_prepare(&q, |
| 1062 | "SELECT uuid" |
| 1063 | " FROM tagxref JOIN blob ON tagxref.rid=blob.rid AND tagxref.tagid=%d" |
| 1064 | " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" |
| 1065 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)" |
| 1066 | " AND NOT EXISTS(SELECT 1 FROM unclustered WHERE rid=blob.rid)" |
| 1067 | " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)%s", |
| 1068 | TAG_CLUSTER, zExtra /*safe-for-%s*/ |
| 1069 | ); |
| 1070 | while( db_step(&q)==SQLITE_ROW ){ |
| 1071 | if( cnt==0 ) blob_appendf(pXfer->pOut, "# sending-clusters\n"); |
| 1072 | blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0)); |
| 1073 | cnt++; |
| 1074 | } |
| 1075 | db_finalize(&q); |
| 1076 | if( cnt ) blob_appendf(pXfer->pOut, "# end-of-clusters\n"); |
| 1077 | return cnt; |
| 1078 | } |
| 1079 | |
| 1080 | /* |
| 1081 | ** Send an igot message for every artifact. |
| 1082 | */ |
| 1083 | static void send_all(Xfer *pXfer){ |
| @@ -1781,10 +1814,19 @@ | |
| 1814 | ** The client sends this message to the server to ask the server |
| 1815 | ** to tell it about alternative repositories in the reply. |
| 1816 | */ |
| 1817 | if( blob_eq(&xfer.aToken[1], "req-links") ){ |
| 1818 | bSendLinks = 1; |
| 1819 | }else |
| 1820 | |
| 1821 | /* pragma req-clusters |
| 1822 | ** |
| 1823 | ** This pragma requests that the server send igot cards for every |
| 1824 | ** cluster artifact that it knows about. |
| 1825 | */ |
| 1826 | if( blob_eq(&xfer.aToken[1], "req-clusters") ){ |
| 1827 | send_all_clusters(&xfer); |
| 1828 | } |
| 1829 | |
| 1830 | }else |
| 1831 | |
| 1832 | /* Unknown message |
| @@ -1981,11 +2023,11 @@ | |
| 2023 | int nCardSent = 0; /* Number of cards sent */ |
| 2024 | int nCardRcvd = 0; /* Number of cards received */ |
| 2025 | int nCycle = 0; /* Number of round trips to the server */ |
| 2026 | int size; /* Size of a config value or uvfile */ |
| 2027 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 2028 | int nFileRecv = 0; /* Number of files received */ |
| 2029 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 2030 | const char *zCookie; /* Server cookie */ |
| 2031 | i64 nUncSent, nUncRcvd; /* Bytes sent and received (before compression) */ |
| 2032 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| 2033 | int cloneSeqno = 1; /* Sequence number for clones */ |
| @@ -2007,10 +2049,11 @@ | |
| 2049 | int uvHashSent = 0; /* The "pragma uv-hash" message has been sent */ |
| 2050 | int uvDoPush = 0; /* Generate uvfile messages to send to server */ |
| 2051 | int uvPullOnly = 0; /* 1: pull-only. 2: pull-only warning issued */ |
| 2052 | int nUvGimmeSent = 0; /* Number of uvgimme cards sent on this cycle */ |
| 2053 | int nUvFileRcvd = 0; /* Number of uvfile cards received on this cycle */ |
| 2054 | int nGimmeRcvd = 0; /* Number of gimme cards recevied on the prev cycle */ |
| 2055 | sqlite3_int64 mtime; /* Modification time on a UV file */ |
| 2056 | int autopushFailed = 0; /* Autopush following commit failed if true */ |
| 2057 | const char *zCkinLock; /* Name of check-in to lock. NULL for none */ |
| 2058 | const char *zClientId; /* A unique identifier for this check-out */ |
| 2059 | unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */ |
| @@ -2181,15 +2224,21 @@ | |
| 2224 | */ |
| 2225 | if( (syncFlags & SYNC_PULL)!=0 |
| 2226 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 2227 | ){ |
| 2228 | request_phantoms(&xfer, mxPhantomReq); |
| 2229 | if( xfer.nGimmeSent>0 && nCycle==2 && (syncFlags & SYNC_PULL)!=0 ){ |
| 2230 | blob_appendf(&send, "pragma req-clusters\n"); |
| 2231 | } |
| 2232 | } |
| 2233 | if( syncFlags & SYNC_PUSH ){ |
| 2234 | send_unsent(&xfer); |
| 2235 | nCardSent += send_unclustered(&xfer); |
| 2236 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 2237 | if( nGimmeRcvd>0 && nCycle==2 ){ |
| 2238 | send_all_clusters(&xfer); |
| 2239 | } |
| 2240 | } |
| 2241 | |
| 2242 | /* Client sends configuration parameter requests. On a clone, delay sending |
| 2243 | ** this until the second cycle since the login card might fail on |
| 2244 | ** the first cycle. |
| @@ -2369,10 +2418,11 @@ | |
| 2418 | nCardSent++; |
| 2419 | } |
| 2420 | go = 0; |
| 2421 | nUvGimmeSent = 0; |
| 2422 | nUvFileRcvd = 0; |
| 2423 | nGimmeRcvd = 0; |
| 2424 | nPriorArtifact = nArtifactRcvd; |
| 2425 | |
| 2426 | /* Process the reply that came back from the server */ |
| 2427 | while( blob_line(&recv, &xfer.line) ){ |
| 2428 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| @@ -2449,11 +2499,14 @@ | |
| 2499 | && blob_is_hname(&xfer.aToken[1]) |
| 2500 | ){ |
| 2501 | remote_unk(&xfer.aToken[1]); |
| 2502 | if( syncFlags & SYNC_PUSH ){ |
| 2503 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 2504 | if( rid ){ |
| 2505 | send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 2506 | nGimmeRcvd++; |
| 2507 | } |
| 2508 | } |
| 2509 | }else |
| 2510 | |
| 2511 | /* igot HASH ?PRIVATEFLAG? |
| 2512 | ** |
| 2513 |