Diff
Not logged in

Differences From:

File src/rebuild.c part of check-in [55342eb9fb] - The bug report generator compiles but still does not work right. by drh on 2008-05-17 14:49:49. [view]

To:

File src/rebuild.c part of check-in [791a513c28] - Improvements to clone performance. Skip cross-linking during the clone the automatically rebuild after the clone. Fixes to rebuild to make sure all artifacts are crosslinked. by drh on 2008-05-18 17:18:41. [view]

@@ -69,13 +69,16 @@
 */
 static int totalSize;       /* Total number of artifacts to process */
 static int processCnt;      /* Number processed so far */
 static int ttyOutput;       /* Do progress output */
+static Bag bagDone;         /* Bag of records rebuilt */
 
 /*
 ** Called after each artifact is processed
 */
-static void rebuild_step_done(void){
+static void rebuild_step_done(rid){
+  assert( bag_find(&bagDone, rid)==0 );
+  bag_insert(&bagDone, rid);
   if( ttyOutput ){
     processCnt++;
     printf("%d (%d%%)...\r", processCnt, (processCnt*100/totalSize));
     fflush(stdout);
@@ -104,9 +107,12 @@
   /* Find all children of artifact rid */
   db_prepare(&q1, "SELECT rid FROM delta WHERE srcid=%d", rid);
   bag_init(&children);
   while( db_step(&q1)==SQLITE_ROW ){
-    bag_insert(&children, db_column_int(&q1, 0));
+    int cid = db_column_int(&q1, 0);
+    if( !bag_find(&bagDone, cid) ){
+      bag_insert(&children, cid);
+    }
   }
   nChild = bag_count(&children);
   db_finalize(&q1);
 
@@ -144,9 +150,9 @@
       blob_reset(pUse);
     }
   }
   bag_clear(&children);
-  rebuild_step_done();
+  rebuild_step_done(rid);
 }
 
 /*
 ** Core function to rebuild the infomration in the derived tables of a
@@ -164,8 +170,9 @@
   Stmt s;
   int errCnt = 0;
   char *zTable;
 
+  bag_init(&bagDone);
   ttyOutput = doOut;
   processCnt = 0;
   db_multi_exec(zSchemaUpdates);
   for(;;){
@@ -205,11 +212,27 @@
     if( size>=0 ){
       Blob content;
       content_get(rid, &content);
       rebuild_step(rid, size, &content);
+    }
+  }
+  db_finalize(&s);
+  db_prepare(&s,
+     "SELECT rid, size FROM blob"
+     " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
+  );
+  while( db_step(&s)==SQLITE_ROW ){
+    int rid = db_column_int(&s, 0);
+    int size = db_column_int(&s, 1);
+    if( size>=0 ){
+      if( !bag_find(&bagDone, rid) ){
+        Blob content;
+        content_get(rid, &content);
+        rebuild_step(rid, size, &content);
+      }
     }else{
       db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
-      rebuild_step_done();
+      rebuild_step_done(rid);
     }
   }
   db_finalize(&s);
   if( ttyOutput ){