Check-in [043d63d4aa]
Not logged in
Overview

SHA1 Hash:043d63d4aa79d9558729452b3eba280e756f00fe
Date: 2008-03-08 19:42:53
User: drh
Comment:Additional speed improvements for clone and rebuild.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/content.c from [7cc68e90ad] to [dbfb1885ae].

@@ -364,12 +364,11 @@
 ** content is already in the database, just return the record ID.
 **
 ** If srcId is specified, then pBlob is delta content from
 ** the srcId record.  srcId might be a phantom.
 **
-** A phantom is written if pBlob==0.  If pBlob==0 or if srcId is
-** specified then the UUID is set to zUuid.  Otherwise zUuid is
+** If srcId is specified then the UUID is set to zUuid.  Otherwise zUuid is
 ** ignored.  In the future this might change such that the content
 ** hash is checked against zUuid to make sure it is correct.
 **
 ** If the record already exists but is a phantom, the pBlob content
 ** is inserted and the phatom becomes a real record.
@@ -382,20 +381,17 @@
   Blob hash;
   int markAsUnclustered = 0;
   int isDephantomize = 0;
 
   assert( g.repositoryOpen );
-  if( pBlob && srcId==0 ){
+  assert( pBlob!=0 );
+  if( srcId==0 ){
     sha1sum_blob(pBlob, &hash);
   }else{
     blob_init(&hash, zUuid, -1);
   }
-  if( pBlob==0 ){
-    size = -1;
-  }else{
-    size = blob_size(pBlob);
-  }
+  size = blob_size(pBlob);
   db_begin_transaction();
 
   /* Check to see if the entry already exists and if it does whether
   ** or not the entry is a phantom
   */
@@ -415,27 +411,26 @@
     markAsUnclustered = 1;
   }
   db_finalize(&s1);
 
   /* Construct a received-from ID if we do not already have one */
-  if( g.rcvid==0 && pBlob!=0 ){
+  if( g.rcvid==0 ){
     db_multi_exec(
        "INSERT INTO rcvfrom(uid, mtime, nonce, ipaddr)"
        "VALUES(%d, julianday('now'), %Q, %Q)",
        g.userUid, g.zNonce, g.zIpAddr
     );
     g.rcvid = db_last_insert_rowid();
   }
 
+  blob_compress(pBlob, &cmpr);
   if( rid>0 ){
     /* We are just adding data to a phantom */
-    assert( pBlob!=0 );
     db_prepare(&s1,
       "UPDATE blob SET rcvid=%d, size=%d, content=:data WHERE rid=%d",
        g.rcvid, size, rid
     );
-    blob_compress(pBlob, &cmpr);
     db_bind_blob(&s1, ":data", &cmpr);
     db_exec(&s1);
     db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
     if( srcId==0 || content_is_available(srcId) ){
       isDephantomize = 1;
@@ -446,20 +441,18 @@
     db_prepare(&s1,
       "INSERT INTO blob(rcvid,size,uuid,content)"
       "VALUES(%d,%d,'%b',:data)",
        g.rcvid, size, &hash
     );
-    if( pBlob ){
-      blob_compress(pBlob, &cmpr);
-      db_bind_blob(&s1, ":data", &cmpr);
-    }
+    blob_compress(pBlob, &cmpr);
     db_exec(&s1);
     rid = db_last_insert_rowid();
     if( !pBlob ){
       db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
     }
   }
+  blob_reset(&cmpr);
 
   /* If the srcId is specified, then the data we just added is
   ** really a delta.  Record this fact in the delta table.
   */
   if( srcId ){
@@ -485,16 +478,40 @@
   db_end_transaction(0);
   blob_reset(&hash);
 
   /* Make arrangements to verify that the data can be recovered
   ** before we commit */
-  if( pBlob ){
-    blob_reset(&cmpr);
-    verify_before_commit(rid);
-  }
+  verify_before_commit(rid);
+  return rid;
+}
+
+/*
+** Create a new phantom with the given UUID and return its artifact ID.
+*/
+int content_new(const char *zUuid){
+  int rid;
+  static Stmt s1, s2;
+
+  assert( g.repositoryOpen );
+  db_begin_transaction();
+  db_static_prepare(&s1,
+    "INSERT INTO blob(rcvid,size,uuid,content)"
+    "VALUES(0,-1,:uuid,NULL)"
+  );
+  db_bind_text(&s1, ":uuid", zUuid);
+  db_exec(&s1);
+  rid = db_last_insert_rowid();
+  db_static_prepare(&s2,
+    "INSERT INTO phantom VALUES(:rid)"
+  );
+  db_bind_int(&s2, ":rid", rid);
+  db_exec(&s2);
+  bag_insert(&contentCache.missing, rid);
+  db_end_transaction(0);
   return rid;
 }
+
 
 /*
 ** COMMAND:  test-content-put
 **
 ** Extract a blob from the database and write it into a file.

Modified src/vfile.c from [429ccc29e5] to [533b750082].

@@ -39,21 +39,29 @@
 ** If the UUID is not found and phantomize is 1, then attempt to
 ** create a phantom record.
 */
 int uuid_to_rid(const char *zUuid, int phantomize){
   int rid, sz;
+  static Stmt q;
   char z[UUID_SIZE+1];
 
   sz = strlen(zUuid);
   if( sz!=UUID_SIZE || !validate16(zUuid, sz) ){
     return 0;
   }
   strcpy(z, zUuid);
   canonical16(z, sz);
-  rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", z);
+  db_static_prepare(&q, "SELECT rid FROM blob WHERE uuid=:uuid");
+  db_bind_text(&q, ":uuid", z);
+  if( db_step(&q)==SQLITE_ROW ){
+    rid = db_column_int(&q, 0);
+  }else{
+    rid = 0;
+  }
+  db_reset(&q);
   if( rid==0 && phantomize ){
-    rid = content_put(0, zUuid, 0);
+    rid = content_new(zUuid);
   }
   return rid;
 }
 
 /*

Modified src/xfer.c from [ac96ad6edd] to [15d6dff0f1].

@@ -56,13 +56,23 @@
 **
 ** Compare to uuid_to_rid().  This routine takes a blob argument
 ** and does less error checking.
 */
 static int rid_from_uuid(Blob *pUuid, int phantomize){
-  int rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%b'", pUuid);
+  static Stmt q;
+  int rid;
+
+  db_static_prepare(&q, "SELECT rid FROM blob WHERE uuid=:uuid");
+  db_bind_str(&q, ":uuid", pUuid);
+  if( db_step(&q)==SQLITE_ROW ){
+    rid = db_column_int(&q, 0);
+  }else{
+    rid = 0;
+  }
+  db_reset(&q);
   if( rid==0 && phantomize ){
-    rid = content_put(0, blob_str(pUuid), 0);
+    rid = content_new(blob_str(pUuid));
   }
   return rid;
 }
 
 /*
@@ -840,20 +850,14 @@
       */
       if( xfer.nToken==2
        && blob_eq(&xfer.aToken[0], "igot")
        && blob_is_uuid(&xfer.aToken[1])
       ){
-        int rid = 0;
-        if( pullFlag || cloneFlag ){
-          if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0",
-                &xfer.aToken[1]) ){
-            rid = content_put(0, blob_str(&xfer.aToken[1]), 0);
-            newPhantom = 1;
-          }
-        }
-        if( rid==0 ){
-          rid = rid_from_uuid(&xfer.aToken[1], 0);
+        int rid = rid_from_uuid(&xfer.aToken[1], 0);
+        if( rid==0 && (pullFlag || cloneFlag) ){
+          rid = content_new(blob_str(&xfer.aToken[1]));
+          newPhantom = 1;
         }
         remote_has(rid);
       }else