Overview
SHA1 Hash: | 16fbb59b96bd8731edd17d952c11fd31e78e1a43 |
---|---|
Date: | 2007-12-03 19:08:11 |
User: | drh |
Comment: | Fix the delta computation on download so that it never tries to delta a file that has the same file as both its parent and its child. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/db.c from [48224de87a] to [dab15ea695].
@@ -71,11 +71,10 @@ cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); - exit(1); exit(1); } static int nBegin = 0; /* Nesting depth of BEGIN */ static int doRollback = 0; /* True to force a rollback */
Modified src/xfer.c from [3c34086239] to [36f1bd8921].
@@ -91,10 +91,11 @@ ** be initialized to an empty string. */ static void xfer_accept_file(Xfer *pXfer){ int n; int rid; + int srcid = 0; Blob content, hash; if( pXfer->nToken<3 || pXfer->nToken>4 || !blob_is_uuid(&pXfer->aToken[1]) @@ -112,11 +113,11 @@ /* Ignore files that have been shunned */ return; } if( pXfer->nToken==4 ){ Blob src; - int srcid = rid_from_uuid(&pXfer->aToken[2], 1); + srcid = rid_from_uuid(&pXfer->aToken[2], 1); if( content_get(srcid, &src)==0 ){ content_put(&content, blob_str(&pXfer->aToken[1]), srcid); blob_appendf(pXfer->pOut, "gimme %b\n", &pXfer->aToken[2]); pXfer->nGimmeSent++; pXfer->nDanglingFile++; @@ -141,35 +142,38 @@ } remote_has(rid); } /* -** Try to send a file as a delta. If successful, return the number -** of bytes in the delta. If not, return zero. -** -** If srcId is specified, use it. If not, try to figure out a -** reasonable srcId. -*/ -static int send_as_delta( +** Try to send a file as a delta against its parent. +** If successful, return the number of bytes in the delta. +** If we cannot generate an appropriate delta, then send +** nothing and return zero. +*/ +static int send_delta_parent( Xfer *pXfer, /* The transfer context */ int rid, /* record id of the file to send */ Blob *pContent, /* The content of the file to send */ - Blob *pUuid, /* The UUID of the file to send */ - int srcId /* Send as a delta against this record */ + Blob *pUuid /* The UUID of the file to send */ ){ static const char *azQuery[] = { - "SELECT pid FROM plink" + "SELECT pid FROM plink x" " WHERE cid=%d" - " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)", - - "SELECT pid FROM mlink" + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" + " AND NOT EXISTS(SELECT 1 FROM plink y" + " WHERE y.pid=x.cid AND y.cid=x.pid)", + + "SELECT pid FROM mlink x" " WHERE fid=%d" - " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)", + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" + " AND NOT EXISTS(SELECT 1 FROM mlink y" + " WHERE y.pid=x.fid AND y.fid=x.pid)" }; int i; Blob src, delta; int size = 0; + int srcId = 0; for(i=0; srcId==0 && i<count(azQuery); i++){ srcId = db_int(0, azQuery[i], rid); } if( srcId>0 && content_get(srcId, &src) ){ @@ -189,21 +193,53 @@ } return size; } /* +** Try to send a file as a native delta. +** If successful, return the number of bytes in the delta. +** If we cannot generate an appropriate delta, then send +** nothing and return zero. +*/ +static int send_delta_native( + Xfer *pXfer, /* The transfer context */ + int rid, /* record id of the file to send */ + Blob *pUuid /* The UUID of the file to send */ +){ + Blob src, delta; + int size = 0; + int srcId; + + srcId = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", rid); + if( srcId>0 ){ + blob_zero(&delta); + db_blob(&delta, "SELECT content FROM blob WHERE rid=%d", rid); + blob_uncompress(&delta, &delta); + blob_zero(&src); + db_blob(&src, "SELECT uuid FROM blob WHERE rid=%d", srcId); + blob_appendf(pXfer->pOut, "file %b %b %d\n", + pUuid, &src, blob_size(&delta)); + blob_append(pXfer->pOut, blob_buffer(&delta), blob_size(&delta)); + size = blob_size(&delta); + blob_reset(&delta); + blob_reset(&src); + }else{ + size = 0; + } + return size; +} + +/* ** Send the file identified by rid. ** ** The pUuid can be NULL in which case the correct UUID is computed ** from the rid. ** -** If srcId is positive, then a delta is sent against that srcId. -** If srcId is zero, then an attempt is made to find an appropriate -** file to delta against. If srcId is negative, the file is sent -** without deltaing. +** Try to send the file as a native delta if nativeDelta is true, or +** as a parent delta if nativeDelta is false. */ -static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){ +static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int nativeDelta){ Blob content, uuid; int size = 0; if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){ return; @@ -220,22 +256,30 @@ blob_appendf(pXfer->pOut, "igot %b\n", pUuid); pXfer->nIGotSent++; blob_reset(&uuid); return; } - content_get(rid, &content); - - if( blob_size(&content)>100 ){ - size = send_as_delta(pXfer, rid, &content, pUuid, srcId); + if( nativeDelta ){ + size = send_delta_native(pXfer, rid, pUuid); + if( size ){ + pXfer->nDeltaSent++; + } } if( size==0 ){ - int size = blob_size(&content); - blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size); - blob_append(pXfer->pOut, blob_buffer(&content), size); - pXfer->nFileSent++; - }else{ - pXfer->nDeltaSent++; + content_get(rid, &content); + + if( !nativeDelta && blob_size(&content)>100 ){ + size = send_delta_parent(pXfer, rid, &content, pUuid); + } + if( size==0 ){ + int size = blob_size(&content); + blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size); + blob_append(pXfer->pOut, blob_buffer(&content), size); + pXfer->nFileSent++; + }else{ + pXfer->nDeltaSent++; + } } remote_has(rid); blob_reset(&uuid); } @@ -412,10 +456,11 @@ void page_xfer(void){ int isPull = 0; int isPush = 0; int nErr = 0; Xfer xfer; + int nativeDeltaFlag = 0; memset(&xfer, 0, sizeof(xfer)); blobarray_zero(xfer.aToken, count(xfer.aToken)); cgi_set_content_type(g.zContentType); blob_zero(&xfer.err); @@ -551,10 +596,11 @@ @ error not\sauthorized\sto\sclone nErr++; break; } isPull = 1; + /* nativeDeltaFlag = 1; */ @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x")) }else /* login USER NONCE SIGNATURE ** @@ -712,11 +758,11 @@ } /* Generate gimme messages for phantoms and leaf messages ** for all leaves. */ - if( pullFlag ){ + if( pullFlag || cloneFlag ){ request_phantoms(&xfer); } if( pushFlag ){ send_unsent(&xfer); nMsg += send_unclustered(&xfer); @@ -791,11 +837,11 @@ && blob_eq(&xfer.aToken[0], "igot") && blob_is_uuid(&xfer.aToken[1]) ){ int rid = 0; nMsg++; - if( pullFlag ){ + if( pullFlag || cloneFlag ){ if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0", &xfer.aToken[1]) ){ rid = content_put(0, blob_str(&xfer.aToken[1]), 0); newPhantom = 1; } @@ -824,13 +870,11 @@ nMsg++; if( zPCode==0 ){ zPCode = mprintf("%b", &xfer.aToken[2]); db_set("project-code", zPCode, 0); } - cloneFlag = 0; - pullFlag = 1; - blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); + blob_appendf(&send, "clone\n"); nMsg++; }else /* cookie TEXT **