Fossil SCM

Small performance tweaks for clone and rebuild.

drh 2010-07-04 21:11 trunk
Commit 710a8ba9938a9fb08a9534dd23c34f1d6c478ddb
3 files changed +15 -4 +6 -5 +6 -5
+15 -4
--- src/content.c
+++ src/content.c
@@ -126,24 +126,25 @@
126126
** show that everything that was formerly unavailable because rid
127127
** was missing is now available.
128128
*/
129129
static void content_mark_available(int rid){
130130
Bag pending;
131
- Stmt q;
131
+ static Stmt q;
132132
if( bag_find(&contentCache.available, rid) ) return;
133133
bag_init(&pending);
134134
bag_insert(&pending, rid);
135135
while( (rid = bag_first(&pending))!=0 ){
136136
bag_remove(&pending, rid);
137137
bag_remove(&contentCache.missing, rid);
138138
bag_insert(&contentCache.available, rid);
139
- db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
139
+ db_static_prepare(&q, "SELECT rid FROM delta WHERE srcid=:rid");
140
+ db_bind_int(&q, ":rid", rid);
140141
while( db_step(&q)==SQLITE_ROW ){
141142
int nx = db_column_int(&q, 0);
142143
bag_insert(&pending, nx);
143144
}
144
- db_finalize(&q);
145
+ db_reset(&q);
145146
}
146147
bag_clear(&pending);
147148
}
148149
149150
/*
@@ -322,16 +323,26 @@
322323
** if that record has other records that are derived by delta,
323324
** then call manifest_crosslink() on those other records.
324325
*/
325326
void after_dephantomize(int rid, int linkFlag){
326327
Stmt q;
328
+ int prevTid = 0;
329
+
330
+ /* The prevTid variable is used to delay invoking this routine
331
+ ** recursively, if possible, until after the query has finalized,
332
+ ** in order to avoid having an excessive number of prepared statements.
333
+ ** This is most effective in the common case where the query returns
334
+ ** just one row.
335
+ */
327336
db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
328337
while( db_step(&q)==SQLITE_ROW ){
329338
int tid = db_column_int(&q, 0);
330
- after_dephantomize(tid, 1);
339
+ if( prevTid ) after_dephantomize(prevTid, 1);
340
+ prevTid = tid;
331341
}
332342
db_finalize(&q);
343
+ if( prevTid ) after_dephantomize(prevTid, 1);
333344
if( linkFlag ){
334345
Blob content;
335346
content_get(rid, &content);
336347
manifest_crosslink(rid, &content);
337348
blob_reset(&content);
338349
--- src/content.c
+++ src/content.c
@@ -126,24 +126,25 @@
126 ** show that everything that was formerly unavailable because rid
127 ** was missing is now available.
128 */
129 static void content_mark_available(int rid){
130 Bag pending;
131 Stmt q;
132 if( bag_find(&contentCache.available, rid) ) return;
133 bag_init(&pending);
134 bag_insert(&pending, rid);
135 while( (rid = bag_first(&pending))!=0 ){
136 bag_remove(&pending, rid);
137 bag_remove(&contentCache.missing, rid);
138 bag_insert(&contentCache.available, rid);
139 db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
 
140 while( db_step(&q)==SQLITE_ROW ){
141 int nx = db_column_int(&q, 0);
142 bag_insert(&pending, nx);
143 }
144 db_finalize(&q);
145 }
146 bag_clear(&pending);
147 }
148
149 /*
@@ -322,16 +323,26 @@
322 ** if that record has other records that are derived by delta,
323 ** then call manifest_crosslink() on those other records.
324 */
325 void after_dephantomize(int rid, int linkFlag){
326 Stmt q;
 
 
 
 
 
 
 
 
327 db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
328 while( db_step(&q)==SQLITE_ROW ){
329 int tid = db_column_int(&q, 0);
330 after_dephantomize(tid, 1);
 
331 }
332 db_finalize(&q);
 
333 if( linkFlag ){
334 Blob content;
335 content_get(rid, &content);
336 manifest_crosslink(rid, &content);
337 blob_reset(&content);
338
--- src/content.c
+++ src/content.c
@@ -126,24 +126,25 @@
126 ** show that everything that was formerly unavailable because rid
127 ** was missing is now available.
128 */
129 static void content_mark_available(int rid){
130 Bag pending;
131 static Stmt q;
132 if( bag_find(&contentCache.available, rid) ) return;
133 bag_init(&pending);
134 bag_insert(&pending, rid);
135 while( (rid = bag_first(&pending))!=0 ){
136 bag_remove(&pending, rid);
137 bag_remove(&contentCache.missing, rid);
138 bag_insert(&contentCache.available, rid);
139 db_static_prepare(&q, "SELECT rid FROM delta WHERE srcid=:rid");
140 db_bind_int(&q, ":rid", rid);
141 while( db_step(&q)==SQLITE_ROW ){
142 int nx = db_column_int(&q, 0);
143 bag_insert(&pending, nx);
144 }
145 db_reset(&q);
146 }
147 bag_clear(&pending);
148 }
149
150 /*
@@ -322,16 +323,26 @@
323 ** if that record has other records that are derived by delta,
324 ** then call manifest_crosslink() on those other records.
325 */
326 void after_dephantomize(int rid, int linkFlag){
327 Stmt q;
328 int prevTid = 0;
329
330 /* The prevTid variable is used to delay invoking this routine
331 ** recursively, if possible, until after the query has finalized,
332 ** in order to avoid having an excessive number of prepared statements.
333 ** This is most effective in the common case where the query returns
334 ** just one row.
335 */
336 db_prepare(&q, "SELECT rid FROM delta WHERE srcid=%d", rid);
337 while( db_step(&q)==SQLITE_ROW ){
338 int tid = db_column_int(&q, 0);
339 if( prevTid ) after_dephantomize(prevTid, 1);
340 prevTid = tid;
341 }
342 db_finalize(&q);
343 if( prevTid ) after_dephantomize(prevTid, 1);
344 if( linkFlag ){
345 Blob content;
346 content_get(rid, &content);
347 manifest_crosslink(rid, &content);
348 blob_reset(&content);
349
+6 -5
--- src/file.c
+++ src/file.c
@@ -197,20 +197,21 @@
197197
** * Does not contain two or more "/" characters in a row.
198198
** * Contains at least one character
199199
*/
200200
int file_is_simple_pathname(const char *z){
201201
int i;
202
- if( *z=='/' || *z==0 ) return 0;
203
- if( *z=='.' ){
202
+ char c = z[0];
203
+ if( c=='/' || c==0 ) return 0;
204
+ if( c=='.' ){
204205
if( z[1]=='/' || z[1]==0 ) return 0;
205206
if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
206207
}
207
- for(i=0; z[i]; i++){
208
- if( z[i]=='\\' || z[i]=='*' || z[i]=='[' || z[i]==']' || z[i]=='?' ){
208
+ for(i=0; (c=z[i])!=0; i++){
209
+ if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
209210
return 0;
210211
}
211
- if( z[i]=='/' ){
212
+ if( c=='/' ){
212213
if( z[i+1]=='/' ) return 0;
213214
if( z[i+1]=='.' ){
214215
if( z[i+2]=='/' || z[i+2]==0 ) return 0;
215216
if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
216217
}
217218
--- src/file.c
+++ src/file.c
@@ -197,20 +197,21 @@
197 ** * Does not contain two or more "/" characters in a row.
198 ** * Contains at least one character
199 */
200 int file_is_simple_pathname(const char *z){
201 int i;
202 if( *z=='/' || *z==0 ) return 0;
203 if( *z=='.' ){
 
204 if( z[1]=='/' || z[1]==0 ) return 0;
205 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
206 }
207 for(i=0; z[i]; i++){
208 if( z[i]=='\\' || z[i]=='*' || z[i]=='[' || z[i]==']' || z[i]=='?' ){
209 return 0;
210 }
211 if( z[i]=='/' ){
212 if( z[i+1]=='/' ) return 0;
213 if( z[i+1]=='.' ){
214 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
215 if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
216 }
217
--- src/file.c
+++ src/file.c
@@ -197,20 +197,21 @@
197 ** * Does not contain two or more "/" characters in a row.
198 ** * Contains at least one character
199 */
200 int file_is_simple_pathname(const char *z){
201 int i;
202 char c = z[0];
203 if( c=='/' || c==0 ) return 0;
204 if( c=='.' ){
205 if( z[1]=='/' || z[1]==0 ) return 0;
206 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
207 }
208 for(i=0; (c=z[i])!=0; i++){
209 if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
210 return 0;
211 }
212 if( c=='/' ){
213 if( z[i+1]=='/' ) return 0;
214 if( z[i+1]=='.' ){
215 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
216 if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
217 }
218
+6 -5
--- src/rebuild.c
+++ src/rebuild.c
@@ -98,11 +98,11 @@
9898
** Rebuild cross-referencing information for the artifact
9999
** rid with content pBase and all of its descendants. This
100100
** routine clears the content buffer before returning.
101101
*/
102102
static void rebuild_step(int rid, int size, Blob *pBase){
103
- Stmt q1;
103
+ static Stmt q1;
104104
Bag children;
105105
Blob copy;
106106
Blob *pUse;
107107
int nChild, i, cid;
108108
@@ -112,20 +112,21 @@
112112
"UPDATE blob SET size=%d WHERE rid=%d", blob_size(pBase), rid
113113
);
114114
}
115115
116116
/* Find all children of artifact rid */
117
- db_prepare(&q1, "SELECT rid FROM delta WHERE srcid=%d", rid);
117
+ db_static_prepare(&q1, "SELECT rid FROM delta WHERE srcid=:rid");
118
+ db_bind_int(&q1, ":rid", rid);
118119
bag_init(&children);
119120
while( db_step(&q1)==SQLITE_ROW ){
120121
int cid = db_column_int(&q1, 0);
121122
if( !bag_find(&bagDone, cid) ){
122123
bag_insert(&children, cid);
123124
}
124125
}
125126
nChild = bag_count(&children);
126
- db_finalize(&q1);
127
+ db_reset(&q1);
127128
128129
/* Crosslink the artifact */
129130
if( nChild==0 ){
130131
pUse = pBase;
131132
}else{
@@ -209,11 +210,11 @@
209210
fflush(stdout);
210211
}
211212
db_multi_exec(zSchemaUpdates);
212213
for(;;){
213214
zTable = db_text(0,
214
- "SELECT name FROM sqlite_master"
215
+ "SELECT name FROM sqlite_master /*scan*/"
215216
" WHERE type='table'"
216217
" AND name NOT IN ('blob','delta','rcvfrom','user',"
217218
"'config','shun','private','reportfmt',"
218219
"'concealed')"
219220
" AND name NOT GLOB 'sqlite_*'"
@@ -237,11 +238,11 @@
237238
db_multi_exec(
238239
"DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')"
239240
);
240241
totalSize = db_int(0, "SELECT count(*) FROM blob");
241242
db_prepare(&s,
242
- "SELECT rid, size FROM blob"
243
+ "SELECT rid, size FROM blob /*scan*/"
243244
" WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
244245
" AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
245246
);
246247
manifest_crosslink_begin();
247248
while( db_step(&s)==SQLITE_ROW ){
248249
--- src/rebuild.c
+++ src/rebuild.c
@@ -98,11 +98,11 @@
98 ** Rebuild cross-referencing information for the artifact
99 ** rid with content pBase and all of its descendants. This
100 ** routine clears the content buffer before returning.
101 */
102 static void rebuild_step(int rid, int size, Blob *pBase){
103 Stmt q1;
104 Bag children;
105 Blob copy;
106 Blob *pUse;
107 int nChild, i, cid;
108
@@ -112,20 +112,21 @@
112 "UPDATE blob SET size=%d WHERE rid=%d", blob_size(pBase), rid
113 );
114 }
115
116 /* Find all children of artifact rid */
117 db_prepare(&q1, "SELECT rid FROM delta WHERE srcid=%d", rid);
 
118 bag_init(&children);
119 while( db_step(&q1)==SQLITE_ROW ){
120 int cid = db_column_int(&q1, 0);
121 if( !bag_find(&bagDone, cid) ){
122 bag_insert(&children, cid);
123 }
124 }
125 nChild = bag_count(&children);
126 db_finalize(&q1);
127
128 /* Crosslink the artifact */
129 if( nChild==0 ){
130 pUse = pBase;
131 }else{
@@ -209,11 +210,11 @@
209 fflush(stdout);
210 }
211 db_multi_exec(zSchemaUpdates);
212 for(;;){
213 zTable = db_text(0,
214 "SELECT name FROM sqlite_master"
215 " WHERE type='table'"
216 " AND name NOT IN ('blob','delta','rcvfrom','user',"
217 "'config','shun','private','reportfmt',"
218 "'concealed')"
219 " AND name NOT GLOB 'sqlite_*'"
@@ -237,11 +238,11 @@
237 db_multi_exec(
238 "DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')"
239 );
240 totalSize = db_int(0, "SELECT count(*) FROM blob");
241 db_prepare(&s,
242 "SELECT rid, size FROM blob"
243 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
244 " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
245 );
246 manifest_crosslink_begin();
247 while( db_step(&s)==SQLITE_ROW ){
248
--- src/rebuild.c
+++ src/rebuild.c
@@ -98,11 +98,11 @@
98 ** Rebuild cross-referencing information for the artifact
99 ** rid with content pBase and all of its descendants. This
100 ** routine clears the content buffer before returning.
101 */
102 static void rebuild_step(int rid, int size, Blob *pBase){
103 static Stmt q1;
104 Bag children;
105 Blob copy;
106 Blob *pUse;
107 int nChild, i, cid;
108
@@ -112,20 +112,21 @@
112 "UPDATE blob SET size=%d WHERE rid=%d", blob_size(pBase), rid
113 );
114 }
115
116 /* Find all children of artifact rid */
117 db_static_prepare(&q1, "SELECT rid FROM delta WHERE srcid=:rid");
118 db_bind_int(&q1, ":rid", rid);
119 bag_init(&children);
120 while( db_step(&q1)==SQLITE_ROW ){
121 int cid = db_column_int(&q1, 0);
122 if( !bag_find(&bagDone, cid) ){
123 bag_insert(&children, cid);
124 }
125 }
126 nChild = bag_count(&children);
127 db_reset(&q1);
128
129 /* Crosslink the artifact */
130 if( nChild==0 ){
131 pUse = pBase;
132 }else{
@@ -209,11 +210,11 @@
210 fflush(stdout);
211 }
212 db_multi_exec(zSchemaUpdates);
213 for(;;){
214 zTable = db_text(0,
215 "SELECT name FROM sqlite_master /*scan*/"
216 " WHERE type='table'"
217 " AND name NOT IN ('blob','delta','rcvfrom','user',"
218 "'config','shun','private','reportfmt',"
219 "'concealed')"
220 " AND name NOT GLOB 'sqlite_*'"
@@ -237,11 +238,11 @@
238 db_multi_exec(
239 "DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')"
240 );
241 totalSize = db_int(0, "SELECT count(*) FROM blob");
242 db_prepare(&s,
243 "SELECT rid, size FROM blob /*scan*/"
244 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
245 " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
246 );
247 manifest_crosslink_begin();
248 while( db_step(&s)==SQLITE_ROW ){
249

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button