Fossil SCM
Use delta compression on elements of a single purgeevent in the graveyard. Record whether or not elements were originally private when moving them into the graveyard.
Commit
916cd4b885eb1370b75fa11fff563e3396dd9685
Parent
cbe1fa51097d2ea…
2 files changed
+40
-14
+2
-2
+40
-14
| --- src/purge.c | ||
| +++ src/purge.c | ||
| @@ -40,12 +40,16 @@ | ||
| 40 | 40 | @ peid INTEGER PRIMARY KEY, -- Unique ID for the purge event |
| 41 | 41 | @ ctime DATETIME, -- When purge occurred. Seconds since 1970. |
| 42 | 42 | @ pnotes TEXT -- Human-readable notes about the purge event |
| 43 | 43 | @ ); |
| 44 | 44 | @ CREATE TABLE IF NOT EXISTS "%w".purgeitem( |
| 45 | +@ piid INTEGER PRIMARY KEY, -- ID for the purge item | |
| 45 | 46 | @ peid INTEGER REFERENCES purgeevent ON DELETE CASCADE, -- Purge event |
| 47 | +@ orid INTEGER, -- Original RID before purged | |
| 46 | 48 | @ uuid TEXT NOT NULL, -- SHA1 hash of the purged artifact |
| 49 | +@ srcid INTEGER, -- Basis purgeitem for delta compression | |
| 50 | +@ isPrivate BOOLEAN, -- True if artifact was originally private | |
| 47 | 51 | @ sz INT NOT NULL, -- Uncompressed size of the purged artifact |
| 48 | 52 | @ data BLOB -- Compressed artifact content |
| 49 | 53 | @ ); |
| 50 | 54 | ; |
| 51 | 55 | |
| @@ -84,11 +88,10 @@ | ||
| 84 | 88 | ){ |
| 85 | 89 | int peid = 0; /* New purgeevent ID */ |
| 86 | 90 | Stmt q; /* General-use prepared statement */ |
| 87 | 91 | |
| 88 | 92 | assert( g.repositoryOpen ); /* Main database must already be open */ |
| 89 | - add_content_sql_commands(g.db); | |
| 90 | 93 | db_begin_transaction(); |
| 91 | 94 | if( purge_baseline_out_from_under_delta(zTab) ){ |
| 92 | 95 | fossil_fatal("attempt to purge a baseline manifest without also purging " |
| 93 | 96 | "all of its deltas"); |
| 94 | 97 | } |
| @@ -103,18 +106,37 @@ | ||
| 103 | 106 | while( db_step(&q)==SQLITE_ROW ){ |
| 104 | 107 | int rid = db_column_int(&q, 0); |
| 105 | 108 | content_undelta(rid); |
| 106 | 109 | verify_before_commit(rid); |
| 107 | 110 | } |
| 111 | + db_finalize(&q); | |
| 112 | + db_prepare(&q, "SELECT rid FROM delta WHERE rid IN \"%w\"" | |
| 113 | + " AND srcid NOT IN \"%w\"", zTab, zTab); | |
| 114 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 115 | + int rid = db_column_int(&q, 0); | |
| 116 | + content_undelta(rid); | |
| 117 | + } | |
| 108 | 118 | db_finalize(&q); |
| 109 | 119 | db_multi_exec( |
| 110 | - "INSERT INTO purgeitem(peid,uuid,sz,data)" | |
| 111 | - " SELECT %d, uuid, size, compress(content(uuid))" | |
| 120 | + "INSERT INTO purgeitem(peid,orid,uuid,sz,isPrivate,data)" | |
| 121 | + " SELECT %d, rid, uuid, size," | |
| 122 | + " EXISTS(SELECT 1 FROM private WHERE private.rid=blob.rid)," | |
| 123 | + " content" | |
| 112 | 124 | " FROM blob WHERE rid IN \"%w\"", |
| 113 | 125 | peid, zTab |
| 126 | + ); | |
| 127 | + db_multi_exec( | |
| 128 | + "UPDATE purgeitem" | |
| 129 | + " SET srcid=(SELECT piid FROM purgeitem px, delta" | |
| 130 | + " WHERE px.orid=delta.srcid" | |
| 131 | + " AND delta.rid=purgeitem.orid)" | |
| 132 | + " WHERE peid=%d", | |
| 133 | + peid | |
| 114 | 134 | ); |
| 115 | 135 | db_multi_exec("DELETE FROM blob WHERE rid IN \"%w\"", zTab); |
| 136 | + db_multi_exec("DELETE FROM delta WHERE rid IN \"%w\"", zTab); | |
| 137 | + db_multi_exec("DELETE FROM delta WHERE srcid IN \"%w\"", zTab); | |
| 116 | 138 | db_multi_exec("DELETE FROM event WHERE objid IN \"%w\"", zTab); |
| 117 | 139 | db_multi_exec("DELETE FROM private WHERE rid IN \"%w\"", zTab); |
| 118 | 140 | db_multi_exec("DELETE FROM mlink WHERE mid IN \"%w\"", zTab); |
| 119 | 141 | db_multi_exec("DELETE FROM plink WHERE pid IN \"%w\"", zTab); |
| 120 | 142 | db_multi_exec("DELETE FROM plink WHERE cid IN \"%w\"", zTab); |
| @@ -225,22 +247,26 @@ | ||
| 225 | 247 | */ |
| 226 | 248 | static void purge_event_content(int peid){ |
| 227 | 249 | Stmt q; |
| 228 | 250 | sqlite3_int64 sz1 = 0; |
| 229 | 251 | sqlite3_int64 sz2 = 0; |
| 230 | - db_prepare(&q, "SELECT uuid, sz, length(data) FROM purgeitem WHERE peid=%d", | |
| 231 | - peid); | |
| 252 | + db_prepare(&q, "SELECT piid, substr(uuid,1,16), srcid, isPrivate," | |
| 253 | + " sz, length(data)" | |
| 254 | + " FROM purgeitem WHERE peid=%d", peid); | |
| 232 | 255 | while( db_step(&q)==SQLITE_ROW ){ |
| 233 | - fossil_print(" %s %10d %10d\n", | |
| 234 | - db_column_text(&q,0), | |
| 235 | - db_column_int(&q,1), | |
| 236 | - db_column_int(&q,2)); | |
| 237 | - sz1 += db_column_int(&q,1); | |
| 238 | - sz2 += db_column_int(&q,2); | |
| 256 | + fossil_print(" %5d %s %4s %c %10d %10d\n", | |
| 257 | + db_column_int(&q,0), | |
| 258 | + db_column_text(&q,1), | |
| 259 | + db_column_text(&q,2), | |
| 260 | + db_column_int(&q,3) ? 'P' : ' ', | |
| 261 | + db_column_int(&q,4), | |
| 262 | + db_column_int(&q,5)); | |
| 263 | + sz1 += db_column_int(&q,4); | |
| 264 | + sz2 += db_column_int(&q,5); | |
| 239 | 265 | } |
| 240 | 266 | db_finalize(&q); |
| 241 | - fossil_print(" %40s %10lld %10lld\n", "Total:", sz1, sz2); | |
| 267 | + fossil_print("%.11c%16s%.8c%10lld %10lld\n", ' ', "Total:", ' ', sz1, sz2); | |
| 242 | 268 | } |
| 243 | 269 | |
| 244 | 270 | /* |
| 245 | 271 | ** COMMAND: purge |
| 246 | 272 | ** |
| @@ -259,12 +285,12 @@ | ||
| 259 | 285 | ** |
| 260 | 286 | ** fossil purge [checkin] TAGS... [--explain] |
| 261 | 287 | ** |
| 262 | 288 | ** Move the checkins identified by TAGS and all of their descendants |
| 263 | 289 | ** out of the repository and into the graveyard. If a TAG is a branch |
| 264 | - name then it means all the checkins on that branch. If the --explain | |
| 265 | - option appears, then the repository and graveyard are unchanged and | |
| 290 | +** name then it means all the checkins on that branch. If the --explain | |
| 291 | +** option appears, then the repository and graveyard are unchanged and | |
| 266 | 292 | ** an explaination of what would have happened is shown instead. |
| 267 | 293 | ** |
| 268 | 294 | ** SUMMARY: |
| 269 | 295 | ** fossil purge [checkin] TAGS... [--explain] |
| 270 | 296 | ** fossil purge list |
| 271 | 297 |
| --- src/purge.c | |
| +++ src/purge.c | |
| @@ -40,12 +40,16 @@ | |
| 40 | @ peid INTEGER PRIMARY KEY, -- Unique ID for the purge event |
| 41 | @ ctime DATETIME, -- When purge occurred. Seconds since 1970. |
| 42 | @ pnotes TEXT -- Human-readable notes about the purge event |
| 43 | @ ); |
| 44 | @ CREATE TABLE IF NOT EXISTS "%w".purgeitem( |
| 45 | @ peid INTEGER REFERENCES purgeevent ON DELETE CASCADE, -- Purge event |
| 46 | @ uuid TEXT NOT NULL, -- SHA1 hash of the purged artifact |
| 47 | @ sz INT NOT NULL, -- Uncompressed size of the purged artifact |
| 48 | @ data BLOB -- Compressed artifact content |
| 49 | @ ); |
| 50 | ; |
| 51 | |
| @@ -84,11 +88,10 @@ | |
| 84 | ){ |
| 85 | int peid = 0; /* New purgeevent ID */ |
| 86 | Stmt q; /* General-use prepared statement */ |
| 87 | |
| 88 | assert( g.repositoryOpen ); /* Main database must already be open */ |
| 89 | add_content_sql_commands(g.db); |
| 90 | db_begin_transaction(); |
| 91 | if( purge_baseline_out_from_under_delta(zTab) ){ |
| 92 | fossil_fatal("attempt to purge a baseline manifest without also purging " |
| 93 | "all of its deltas"); |
| 94 | } |
| @@ -103,18 +106,37 @@ | |
| 103 | while( db_step(&q)==SQLITE_ROW ){ |
| 104 | int rid = db_column_int(&q, 0); |
| 105 | content_undelta(rid); |
| 106 | verify_before_commit(rid); |
| 107 | } |
| 108 | db_finalize(&q); |
| 109 | db_multi_exec( |
| 110 | "INSERT INTO purgeitem(peid,uuid,sz,data)" |
| 111 | " SELECT %d, uuid, size, compress(content(uuid))" |
| 112 | " FROM blob WHERE rid IN \"%w\"", |
| 113 | peid, zTab |
| 114 | ); |
| 115 | db_multi_exec("DELETE FROM blob WHERE rid IN \"%w\"", zTab); |
| 116 | db_multi_exec("DELETE FROM event WHERE objid IN \"%w\"", zTab); |
| 117 | db_multi_exec("DELETE FROM private WHERE rid IN \"%w\"", zTab); |
| 118 | db_multi_exec("DELETE FROM mlink WHERE mid IN \"%w\"", zTab); |
| 119 | db_multi_exec("DELETE FROM plink WHERE pid IN \"%w\"", zTab); |
| 120 | db_multi_exec("DELETE FROM plink WHERE cid IN \"%w\"", zTab); |
| @@ -225,22 +247,26 @@ | |
| 225 | */ |
| 226 | static void purge_event_content(int peid){ |
| 227 | Stmt q; |
| 228 | sqlite3_int64 sz1 = 0; |
| 229 | sqlite3_int64 sz2 = 0; |
| 230 | db_prepare(&q, "SELECT uuid, sz, length(data) FROM purgeitem WHERE peid=%d", |
| 231 | peid); |
| 232 | while( db_step(&q)==SQLITE_ROW ){ |
| 233 | fossil_print(" %s %10d %10d\n", |
| 234 | db_column_text(&q,0), |
| 235 | db_column_int(&q,1), |
| 236 | db_column_int(&q,2)); |
| 237 | sz1 += db_column_int(&q,1); |
| 238 | sz2 += db_column_int(&q,2); |
| 239 | } |
| 240 | db_finalize(&q); |
| 241 | fossil_print(" %40s %10lld %10lld\n", "Total:", sz1, sz2); |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | ** COMMAND: purge |
| 246 | ** |
| @@ -259,12 +285,12 @@ | |
| 259 | ** |
| 260 | ** fossil purge [checkin] TAGS... [--explain] |
| 261 | ** |
| 262 | ** Move the checkins identified by TAGS and all of their descendants |
| 263 | ** out of the repository and into the graveyard. If a TAG is a branch |
| 264 | name then it means all the checkins on that branch. If the --explain |
| 265 | option appears, then the repository and graveyard are unchanged and |
| 266 | ** an explaination of what would have happened is shown instead. |
| 267 | ** |
| 268 | ** SUMMARY: |
| 269 | ** fossil purge [checkin] TAGS... [--explain] |
| 270 | ** fossil purge list |
| 271 |
| --- src/purge.c | |
| +++ src/purge.c | |
| @@ -40,12 +40,16 @@ | |
| 40 | @ peid INTEGER PRIMARY KEY, -- Unique ID for the purge event |
| 41 | @ ctime DATETIME, -- When purge occurred. Seconds since 1970. |
| 42 | @ pnotes TEXT -- Human-readable notes about the purge event |
| 43 | @ ); |
| 44 | @ CREATE TABLE IF NOT EXISTS "%w".purgeitem( |
| 45 | @ piid INTEGER PRIMARY KEY, -- ID for the purge item |
| 46 | @ peid INTEGER REFERENCES purgeevent ON DELETE CASCADE, -- Purge event |
| 47 | @ orid INTEGER, -- Original RID before purged |
| 48 | @ uuid TEXT NOT NULL, -- SHA1 hash of the purged artifact |
| 49 | @ srcid INTEGER, -- Basis purgeitem for delta compression |
| 50 | @ isPrivate BOOLEAN, -- True if artifact was originally private |
| 51 | @ sz INT NOT NULL, -- Uncompressed size of the purged artifact |
| 52 | @ data BLOB -- Compressed artifact content |
| 53 | @ ); |
| 54 | ; |
| 55 | |
| @@ -84,11 +88,10 @@ | |
| 88 | ){ |
| 89 | int peid = 0; /* New purgeevent ID */ |
| 90 | Stmt q; /* General-use prepared statement */ |
| 91 | |
| 92 | assert( g.repositoryOpen ); /* Main database must already be open */ |
| 93 | db_begin_transaction(); |
| 94 | if( purge_baseline_out_from_under_delta(zTab) ){ |
| 95 | fossil_fatal("attempt to purge a baseline manifest without also purging " |
| 96 | "all of its deltas"); |
| 97 | } |
| @@ -103,18 +106,37 @@ | |
| 106 | while( db_step(&q)==SQLITE_ROW ){ |
| 107 | int rid = db_column_int(&q, 0); |
| 108 | content_undelta(rid); |
| 109 | verify_before_commit(rid); |
| 110 | } |
| 111 | db_finalize(&q); |
| 112 | db_prepare(&q, "SELECT rid FROM delta WHERE rid IN \"%w\"" |
| 113 | " AND srcid NOT IN \"%w\"", zTab, zTab); |
| 114 | while( db_step(&q)==SQLITE_ROW ){ |
| 115 | int rid = db_column_int(&q, 0); |
| 116 | content_undelta(rid); |
| 117 | } |
| 118 | db_finalize(&q); |
| 119 | db_multi_exec( |
| 120 | "INSERT INTO purgeitem(peid,orid,uuid,sz,isPrivate,data)" |
| 121 | " SELECT %d, rid, uuid, size," |
| 122 | " EXISTS(SELECT 1 FROM private WHERE private.rid=blob.rid)," |
| 123 | " content" |
| 124 | " FROM blob WHERE rid IN \"%w\"", |
| 125 | peid, zTab |
| 126 | ); |
| 127 | db_multi_exec( |
| 128 | "UPDATE purgeitem" |
| 129 | " SET srcid=(SELECT piid FROM purgeitem px, delta" |
| 130 | " WHERE px.orid=delta.srcid" |
| 131 | " AND delta.rid=purgeitem.orid)" |
| 132 | " WHERE peid=%d", |
| 133 | peid |
| 134 | ); |
| 135 | db_multi_exec("DELETE FROM blob WHERE rid IN \"%w\"", zTab); |
| 136 | db_multi_exec("DELETE FROM delta WHERE rid IN \"%w\"", zTab); |
| 137 | db_multi_exec("DELETE FROM delta WHERE srcid IN \"%w\"", zTab); |
| 138 | db_multi_exec("DELETE FROM event WHERE objid IN \"%w\"", zTab); |
| 139 | db_multi_exec("DELETE FROM private WHERE rid IN \"%w\"", zTab); |
| 140 | db_multi_exec("DELETE FROM mlink WHERE mid IN \"%w\"", zTab); |
| 141 | db_multi_exec("DELETE FROM plink WHERE pid IN \"%w\"", zTab); |
| 142 | db_multi_exec("DELETE FROM plink WHERE cid IN \"%w\"", zTab); |
| @@ -225,22 +247,26 @@ | |
| 247 | */ |
| 248 | static void purge_event_content(int peid){ |
| 249 | Stmt q; |
| 250 | sqlite3_int64 sz1 = 0; |
| 251 | sqlite3_int64 sz2 = 0; |
| 252 | db_prepare(&q, "SELECT piid, substr(uuid,1,16), srcid, isPrivate," |
| 253 | " sz, length(data)" |
| 254 | " FROM purgeitem WHERE peid=%d", peid); |
| 255 | while( db_step(&q)==SQLITE_ROW ){ |
| 256 | fossil_print(" %5d %s %4s %c %10d %10d\n", |
| 257 | db_column_int(&q,0), |
| 258 | db_column_text(&q,1), |
| 259 | db_column_text(&q,2), |
| 260 | db_column_int(&q,3) ? 'P' : ' ', |
| 261 | db_column_int(&q,4), |
| 262 | db_column_int(&q,5)); |
| 263 | sz1 += db_column_int(&q,4); |
| 264 | sz2 += db_column_int(&q,5); |
| 265 | } |
| 266 | db_finalize(&q); |
| 267 | fossil_print("%.11c%16s%.8c%10lld %10lld\n", ' ', "Total:", ' ', sz1, sz2); |
| 268 | } |
| 269 | |
| 270 | /* |
| 271 | ** COMMAND: purge |
| 272 | ** |
| @@ -259,12 +285,12 @@ | |
| 285 | ** |
| 286 | ** fossil purge [checkin] TAGS... [--explain] |
| 287 | ** |
| 288 | ** Move the checkins identified by TAGS and all of their descendants |
| 289 | ** out of the repository and into the graveyard. If a TAG is a branch |
| 290 | ** name then it means all the checkins on that branch. If the --explain |
| 291 | ** option appears, then the repository and graveyard are unchanged and |
| 292 | ** an explaination of what would have happened is shown instead. |
| 293 | ** |
| 294 | ** SUMMARY: |
| 295 | ** fossil purge [checkin] TAGS... [--explain] |
| 296 | ** fossil purge list |
| 297 |
+2
-2
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -80,12 +80,12 @@ | ||
| 80 | 80 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 81 | 81 | @ content BLOB, -- Compressed content of this record |
| 82 | 82 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 83 | 83 | @ ); |
| 84 | 84 | @ CREATE TABLE delta( |
| 85 | -@ rid INTEGER PRIMARY KEY, -- BLOB entry where content is delta-compressed | |
| 86 | -@ srcid INTEGER NOT NULL REFERENCES blob -- BLOB entry holding delta baseline | |
| 85 | +@ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed | |
| 86 | +@ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression | |
| 87 | 87 | @ ); |
| 88 | 88 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 89 | 89 | @ |
| 90 | 90 | @ ------------------------------------------------------------------------- |
| 91 | 91 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 92 | 92 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -80,12 +80,12 @@ | |
| 80 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 81 | @ content BLOB, -- Compressed content of this record |
| 82 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 83 | @ ); |
| 84 | @ CREATE TABLE delta( |
| 85 | @ rid INTEGER PRIMARY KEY, -- BLOB entry where content is delta-compressed |
| 86 | @ srcid INTEGER NOT NULL REFERENCES blob -- BLOB entry holding delta baseline |
| 87 | @ ); |
| 88 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 89 | @ |
| 90 | @ ------------------------------------------------------------------------- |
| 91 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 92 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -80,12 +80,12 @@ | |
| 80 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 81 | @ content BLOB, -- Compressed content of this record |
| 82 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 83 | @ ); |
| 84 | @ CREATE TABLE delta( |
| 85 | @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed |
| 86 | @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression |
| 87 | @ ); |
| 88 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 89 | @ |
| 90 | @ ------------------------------------------------------------------------- |
| 91 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 92 |