Fossil SCM

Simplify the computation of descendants using a recursive CTE.

drh 2015-05-24 00:53 trunk
Commit 31fcde837d45500d8681f4660ca4f7a06e3ef509
1 file changed +12 -29
+12 -29
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255255
/*
256256
** Load the record ID rid and up to N-1 closest descendants into
257257
** the "ok" table.
258258
*/
259259
void compute_descendants(int rid, int N){
260
- Bag seen;
261
- PQueue queue;
262
- Stmt ins;
263
- Stmt q;
264
-
265
- bag_init(&seen);
266
- pqueuex_init(&queue);
267
- bag_insert(&seen, rid);
268
- pqueuex_insert(&queue, rid, 0.0, 0);
269
- db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
270
- db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid");
271
- while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
272
- db_bind_int(&ins, ":rid", rid);
273
- db_step(&ins);
274
- db_reset(&ins);
275
- db_bind_int(&q, ":rid", rid);
276
- while( db_step(&q)==SQLITE_ROW ){
277
- int pid = db_column_int(&q, 0);
278
- double mtime = db_column_double(&q, 1);
279
- if( bag_insert(&seen, pid) ){
280
- pqueuex_insert(&queue, pid, mtime, 0);
281
- }
282
- }
283
- db_reset(&q);
284
- }
285
- bag_clear(&seen);
286
- pqueuex_clear(&queue);
287
- db_finalize(&ins);
288
- db_finalize(&q);
260
+ db_multi_exec(
261
+ "WITH RECURSIVE"
262
+ " dx(rid,mtime) AS ("
263
+ " SELECT %d, 0"
264
+ " UNION"
265
+ " SELECT plink.cid, plink.mtime FROM dx, plink"
266
+ " WHERE plink.pid=dx.rid"
267
+ " ORDER BY 2"
268
+ " )"
269
+ "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
270
+ rid, N
271
+ );
289272
}
290273
291274
/*
292275
** COMMAND: descendants*
293276
**
294277
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255 /*
256 ** Load the record ID rid and up to N-1 closest descendants into
257 ** the "ok" table.
258 */
259 void compute_descendants(int rid, int N){
260 Bag seen;
261 PQueue queue;
262 Stmt ins;
263 Stmt q;
264
265 bag_init(&seen);
266 pqueuex_init(&queue);
267 bag_insert(&seen, rid);
268 pqueuex_insert(&queue, rid, 0.0, 0);
269 db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
270 db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid");
271 while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
272 db_bind_int(&ins, ":rid", rid);
273 db_step(&ins);
274 db_reset(&ins);
275 db_bind_int(&q, ":rid", rid);
276 while( db_step(&q)==SQLITE_ROW ){
277 int pid = db_column_int(&q, 0);
278 double mtime = db_column_double(&q, 1);
279 if( bag_insert(&seen, pid) ){
280 pqueuex_insert(&queue, pid, mtime, 0);
281 }
282 }
283 db_reset(&q);
284 }
285 bag_clear(&seen);
286 pqueuex_clear(&queue);
287 db_finalize(&ins);
288 db_finalize(&q);
289 }
290
291 /*
292 ** COMMAND: descendants*
293 **
294
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255 /*
256 ** Load the record ID rid and up to N-1 closest descendants into
257 ** the "ok" table.
258 */
259 void compute_descendants(int rid, int N){
260 db_multi_exec(
261 "WITH RECURSIVE"
262 " dx(rid,mtime) AS ("
263 " SELECT %d, 0"
264 " UNION"
265 " SELECT plink.cid, plink.mtime FROM dx, plink"
266 " WHERE plink.pid=dx.rid"
267 " ORDER BY 2"
268 " )"
269 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
270 rid, N
271 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272 }
273
274 /*
275 ** COMMAND: descendants*
276 **
277

Keyboard Shortcuts

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