Diff
Not logged in

Differences From:

File src/xfer.c part of check-in [a241c8111c] - Begin adding code to the sync logic to transfer configuration options upon request. by drh on 2008-05-17 22:18:44. [view]

To:

File src/xfer.c part of check-in [243e02bfbd] - Improvements to cloning performance. by drh on 2008-05-18 15:51:05. [view]

@@ -66,10 +66,10 @@
   Blob line;          /* The current line of input */
   Blob aToken[5];     /* Tokenized version of line */
   Blob err;           /* Error message text */
   int nToken;         /* Number of tokens in line */
-  int nIGotSent;      /* Number of "igot" messages sent */
-  int nGimmeSent;     /* Number of gimme messages sent */
+  int nIGotSent;      /* Number of "igot" cards sent */
+  int nGimmeSent;     /* Number of gimme cards sent */
   int nFileSent;      /* Number of files sent */
   int nDeltaSent;     /* Number of deltas sent */
   int nFileRcvd;      /* Number of files received */
   int nDeltaRcvd;     /* Number of deltas received */
@@ -171,13 +171,14 @@
   sha1sum_blob(&content, &hash);
   if( !blob_eq_str(&pXfer->aToken[1], blob_str(&hash), -1) ){
     blob_appendf(&pXfer->err, "content does not match sha1 hash");
   }
-  blob_reset(&hash);
-  rid = content_put(&content, 0, 0);
+  rid = content_put(&content, blob_str(&hash), 0);
+  blob_reset(&hash);
   if( rid==0 ){
     blob_appendf(&pXfer->err, "%s", g.zErrMsg);
   }else{
+    /* db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid); */
     manifest_crosslink(rid, &content);
   }
   remote_has(rid);
 }
@@ -461,9 +462,9 @@
 }
 
 /*
 ** Send an igot message for every entry in unclustered table.
-** Return the number of messages sent.
+** Return the number of cards sent.
 */
 static int send_unclustered(Xfer *pXfer){
   Stmt q;
   int cnt = 0;
@@ -476,8 +477,20 @@
     cnt++;
   }
   db_finalize(&q);
   return cnt;
+}
+
+/*
+** Send an igot message for every artifact.
+*/
+static void send_all(Xfer *pXfer){
+  Stmt q;
+  db_prepare(&q, "SELECT uuid FROM blob");
+  while( db_step(&q)==SQLITE_ROW ){
+    blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
+  }
+  db_finalize(&q);
 }
 
 /*
 ** If this variable is set, disable login checks.  Used for debugging
@@ -497,8 +510,10 @@
   int isPush = 0;
   int nErr = 0;
   Xfer xfer;
   int deltaFlag = 0;
+  int isClone = 0;
+  int nGimme = 0;
 
   memset(&xfer, 0, sizeof(xfer));
   blobarray_zero(xfer.aToken, count(xfer.aToken));
   cgi_set_content_type(g.zContentType);
@@ -542,8 +557,9 @@
     if( blob_eq(&xfer.aToken[0], "gimme")
      && xfer.nToken==2
      && blob_is_uuid(&xfer.aToken[1])
     ){
+      nGimme++;
       if( isPull ){
         int rid = rid_from_uuid(&xfer.aToken[1], 0);
         if( rid ){
           send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
@@ -635,8 +651,9 @@
         @ error not\sauthorized\sto\sclone
         nErr++;
         break;
       }
+      isClone = 1;
       isPull = 1;
       deltaFlag = 1;
       @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x"))
     }else
@@ -699,9 +716,18 @@
   }
   if( isPush ){
     request_phantoms(&xfer, 500);
   }
-  if( isPull ){
+  if( isClone && nGimme==0 ){
+    /* The initial "clone" message from client to server contains no
+    ** "gimme" cards. On that initial message, send the client an "igot"
+    ** card for every artifact currently in the respository.  This will
+    ** cause the client to create phantoms for all artifacts, which will
+    ** in turn make sure that the entire repository is sent efficiently
+    ** and expeditiously.
+    */
+    send_all(&xfer);
+  }else if( isPull ){
     create_cluster();
     send_unclustered(&xfer);
   }
   db_end_transaction(0);
@@ -739,8 +765,14 @@
   page_xfer();
   printf("%s\n", cgi_extract_content(&notUsed));
 }
 
+/*
+** Format strings for progress reporting.
+*/
+static const char zLabel[] = "%-10s %10s %10s %10s %10s %10s\n";
+static const char zValue[] = "\r%-10s %10d %10d %10d %10d %10d\n";
+
 
 /*
 ** Sync to the host identified in g.urlName and g.urlPath.  This
 ** routine is called by the client.
@@ -752,9 +784,9 @@
 void client_sync(int pushFlag, int pullFlag, int cloneFlag){
   int go = 1;        /* Loop until zero */
   const char *zSCode = db_get("server-code", "x");
   const char *zPCode = db_get("project-code", 0);
-  int nMsg = 0;          /* Number of messages sent or received */
+  int nCard = 0;         /* Number of cards sent or received */
   int nCycle = 0;        /* Number of round trips to the server */
   int nFileSend = 0;
   int nFileRecv;          /* Number of files received */
   int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
@@ -787,19 +819,19 @@
   if( cloneFlag ){
     blob_appendf(&send, "clone\n");
     pushFlag = 0;
     pullFlag = 0;
-    nMsg++;
+    nCard++;
     /* TBD: Request all transferable configuration values */
   }else if( pullFlag ){
     blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
-    nMsg++;
+    nCard++;
   }
   if( pushFlag ){
     blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
-    nMsg++;
+    nCard++;
   }
-
+  printf(zLabel, "", "Bytes", "Cards", "Artifacts", "Deltas", "Dangling");
 
   while( go ){
     int newPhantom = 0;
 
@@ -810,25 +842,30 @@
     if( zCookie ){
       blob_appendf(&send, "cookie %s\n", zCookie);
     }
 
-    /* Generate gimme messages for phantoms and leaf messages
+    /* Generate gimme cards for phantoms and leaf cards
     ** for all leaves.
     */
     if( pullFlag || cloneFlag ){
       request_phantoms(&xfer, mxPhantomReq);
     }
     if( pushFlag ){
       send_unsent(&xfer);
-      nMsg += send_unclustered(&xfer);
+      nCard += send_unclustered(&xfer);
     }
 
     /* Exchange messages with the server */
     nFileSend = xfer.nFileSent + xfer.nDeltaSent;
-    printf("Sent:      %10d bytes, %5d messages, %5d files (%d+%d)\n",
-            blob_size(&send), nMsg+xfer.nGimmeSent+xfer.nIGotSent,
+    printf(zValue, "Send:",
+            blob_size(&send), nCard+xfer.nGimmeSent+xfer.nIGotSent,
+            xfer.nFileSent, xfer.nDeltaSent, 0);
+#if 0
+    printf("Sent:      %10d bytes, %5d cards, %5d files (%d+%d)\n",
+            blob_size(&send), nCard+xfer.nGimmeSent+xfer.nIGotSent,
             nFileSend, xfer.nFileSent, xfer.nDeltaSent);
-    nMsg = 0;
+#endif
+    nCard = 0;
     xfer.nFileSent = 0;
     xfer.nDeltaSent = 0;
     xfer.nGimmeSent = 0;
     fflush(stdout);
@@ -835,17 +872,17 @@
     http_exchange(&send, &recv);
     blob_reset(&send);
 
     /* Begin constructing the next message (which might never be
-    ** sent) by beginning with the pull or push messages
+    ** sent) by beginning with the pull or push cards
     */
     if( pullFlag ){
       blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
-      nMsg++;
+      nCard++;
     }
     if( pushFlag ){
       blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
-      nMsg++;
+      nCard++;
     }
 
     /* Process the reply that came back from the server */
     while( blob_line(&recv, &xfer.line) ){
@@ -852,10 +889,10 @@
       if( blob_buffer(&xfer.line)[0]=='#' ){
         continue;
       }
       xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
-      nMsg++;
-      printf("\r%d", nMsg);
+      nCard++;
+      printf("\r%d", nCard);
       fflush(stdout);
 
       /*   file UUID SIZE \n CONTENT
       **   file UUID DELTASRC SIZE \n CONTENT
@@ -921,9 +958,9 @@
           zPCode = mprintf("%b", &xfer.aToken[2]);
           db_set("project-code", zPCode, 0);
         }
         blob_appendf(&send, "clone\n");
-        nMsg++;
+        nCard++;
       }else
 
       /*   config NAME SIZE \n CONTENT
       **
@@ -979,13 +1016,17 @@
       }
       blobarray_reset(xfer.aToken, xfer.nToken);
       blob_reset(&xfer.line);
     }
-    printf("\rReceived:  %10d bytes, %5d messages, %5d files (%d+%d+%d)\n",
-            blob_size(&recv), nMsg,
+    printf(zValue, "Received:",
+            blob_size(&recv), nCard,
+            xfer.nFileRcvd, xfer.nDeltaRcvd, xfer.nDanglingFile);
+#if 0
+    printf("\rReceived:  %10d bytes, %5d cards, %5d files (%d+%d+%d)\n",
+            blob_size(&recv), nCard,
             xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile,
             xfer.nFileRcvd, xfer.nDeltaRcvd, xfer.nDanglingFile);
-
+#endif
     blob_reset(&recv);
     nCycle++;
     go = 0;
 
@@ -997,9 +1038,9 @@
       go = 1;
       mxPhantomReq = nFileRecv*2;
       if( mxPhantomReq<200 ) mxPhantomReq = 200;
     }
-    nMsg = 0;
+    nCard = 0;
     xfer.nFileRcvd = 0;
     xfer.nDeltaRcvd = 0;
     xfer.nDanglingFile = 0;