Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Performance improvements on the compute_leavs() routine. There is opportunity for further improvement in this area. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
6953ca813cce7f2275dde00ff6ebac44 |
| User & Date: | drh 2009-08-27 15:00:33.000 |
Context
|
2009-08-27
| ||
| 18:33 | Various small performance enhancements. check-in: 4c37130fde user: drh tags: trunk | |
| 15:00 | Performance improvements on the compute_leavs() routine. There is opportunity for further improvement in this area. check-in: 6953ca813c user: drh tags: trunk | |
| 14:04 | Performance improvements to the "bag" object. check-in: 1409fbe38c user: drh tags: trunk | |
Changes
Changes to src/descendants.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 | #include <assert.h> /* ** Create a temporary table named "leaves" if it does not ** already exist. Load this table with the RID of all ** check-ins that are leaves which are decended from | | > < < < < < | > > | > > > > > > > | < | > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
#include <assert.h>
/*
** Create a temporary table named "leaves" if it does not
** already exist. Load this table with the RID of all
** check-ins that are leaves which are decended from
** check-in iBase. If iBase==0, find all leaves within the
** entire check-in hierarchy.
**
** A "leaf" is a check-in that has no children in the same branch.
**
** The closeMode flag determines behavior associated with the "closed"
** tag:
**
** closeMode==0 Show all leaves regardless of the "closed" tag.
**
** closeMode==1 Show only leaves without the "closed" tag.
**
** closeMode==2 Show only leaves with the "closed" tag.
**
** The default behavior is to ignore closed leaves (closeMode==0). To
** Show all leaves, use closeMode==1. To show only closed leaves, use
** closeMode==2.
*/
void compute_leaves(int iBase, int closeMode){
/* Create the LEAVES table if it does not already exist. Make sure
** it is empty.
*/
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS leaves("
" rid INTEGER PRIMARY KEY"
");"
"DELETE FROM leaves;"
);
/* We are checking all descendants of iBase. If iBase==0, then
** use a short-cut to find all leaves anywhere in the hierarchy.
*/
if( iBase<=0 ){
db_multi_exec(
"INSERT OR IGNORE INTO leaves"
" SELECT cid FROM plink"
" EXCEPT"
" SELECT pid FROM plink"
" WHERE coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=plink.pid),'trunk')"
" == coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=plink.cid),'trunk');",
TAG_BRANCH, TAG_BRANCH
);
}else{
Bag seen; /* Descendants seen */
Bag pending; /* Unpropagated descendants */
Stmt q1; /* Query to find children of a check-in */
Stmt isBr; /* Query to check to see if a check-in starts a new branch */
Stmt ins; /* INSERT statement for a new record */
/* Initialize the bags. */
bag_init(&seen);
bag_init(&pending);
bag_insert(&pending, iBase);
/* This query returns all non-branch-merge children of check-in :rid.
**
** If a a child is a merge of a fork within the same branch, it is
** returned. Only merge children in different branches are excluded.
*/
db_prepare(&q1,
"SELECT cid FROM plink"
" WHERE pid=:rid"
" AND (isprim"
" OR coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=plink.pid), 'trunk')"
"=coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=plink.cid), 'trunk'))",
TAG_BRANCH, TAG_BRANCH
);
/* This query returns a single row if check-in :rid is the first
** check-in of a new branch.
*/
db_prepare(&isBr,
"SELECT 1 FROM tagxref"
" WHERE rid=:rid AND tagid=%d AND tagtype=2"
" AND srcid>0",
TAG_BRANCH
);
/* This statement inserts check-in :rid into the LEAVES table.
*/
db_prepare(&ins, "INSERT OR IGNORE INTO leaves VALUES(:rid)");
while( bag_count(&pending) ){
int rid = bag_first(&pending);
int cnt = 0;
bag_remove(&pending, rid);
db_bind_int(&q1, ":rid", rid);
while( db_step(&q1)==SQLITE_ROW ){
int cid = db_column_int(&q1, 0);
if( bag_insert(&seen, cid) ){
bag_insert(&pending, cid);
}
db_bind_int(&isBr, ":rid", cid);
if( db_step(&isBr)==SQLITE_DONE ){
cnt++;
}
db_reset(&isBr);
}
db_reset(&q1);
if( cnt==0 && !is_a_leaf(rid) ){
cnt++;
}
if( cnt==0 ){
db_bind_int(&ins, ":rid", rid);
db_step(&ins);
db_reset(&ins);
}
}
db_finalize(&ins);
db_finalize(&isBr);
db_finalize(&q1);
bag_clear(&pending);
bag_clear(&seen);
}
if( closeMode==1 ){
db_multi_exec(
"DELETE FROM leaves WHERE rid IN"
" (SELECT leaves.rid FROM leaves, tagxref"
" WHERE tagxref.rid=leaves.rid "
" AND tagxref.tagid=%d"
" AND tagxref.tagtype>0)",
|
| ︙ | ︙ |