Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Progress toward delta compression on the xfer protocol. The compression works well. But the client is not telling the server what files it has so the server does not have anything to delta against. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
eea381f416beab14a5356f36f1c9108b |
| User & Date: | drh 2007-08-09 03:19:18.000 |
Context
|
2007-08-09
| ||
| 03:44 | Fix a bug in the xfer server that prevents it from receiving deltas. ... (check-in: 869534e182 user: drh tags: trunk) | |
| 03:19 | Progress toward delta compression on the xfer protocol. The compression works well. But the client is not telling the server what files it has so the server does not have anything to delta against. ... (check-in: eea381f416 user: drh tags: trunk) | |
| 01:08 | Website updates. ... (check-in: b110d77c36 user: drh tags: trunk) | |
Changes
Changes to src/rebuild.c.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
forceFlag = find_option("force","f",0)!=0;
if( g.argc!=3 ){
usage("REPOSITORY-FILENAME");
}
errCnt = 0;
db_open_repository(g.argv[2]);
db_begin_transaction();
for(;;){
zTable = db_text(0,
"SELECT name FROM sqlite_master"
" WHERE type='table'"
" AND name NOT IN ('blob','delta','rcvfrom','user','config')");
if( zTable==0 ) break;
db_multi_exec("DROP TABLE %Q", zTable);
| > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
forceFlag = find_option("force","f",0)!=0;
if( g.argc!=3 ){
usage("REPOSITORY-FILENAME");
}
errCnt = 0;
db_open_repository(g.argv[2]);
db_begin_transaction();
db_multi_exec(
"CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid);"
);
for(;;){
zTable = db_text(0,
"SELECT name FROM sqlite_master"
" WHERE type='table'"
" AND name NOT IN ('blob','delta','rcvfrom','user','config')");
if( zTable==0 ) break;
db_multi_exec("DROP TABLE %Q", zTable);
|
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 | @ uuid TEXT UNIQUE, -- SHA1 hash of the content @ content BLOB -- Compressed content of this record @ ); @ CREATE TABLE delta( @ rid INTEGER PRIMARY KEY, -- Record ID @ srcid INTEGER NOT NULL REFERENCES blob -- Record holding source document @ ); @ @ -- Whenever new blobs are received into the repository, an entry @ -- in this table records the source of the blob. @ -- @ CREATE TABLE rcvfrom( @ rcvid INTEGER PRIMARY KEY, -- Received-From ID @ uid INTEGER REFERENCES user, -- User login | > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | @ uuid TEXT UNIQUE, -- SHA1 hash of the content @ content BLOB -- Compressed content of this record @ ); @ CREATE TABLE delta( @ rid INTEGER PRIMARY KEY, -- Record ID @ srcid INTEGER NOT NULL REFERENCES blob -- Record holding source document @ ); @ CREATE INDEX delta_i1 ON delta(srcid); @ @ -- Whenever new blobs are received into the repository, an entry @ -- in this table records the source of the blob. @ -- @ CREATE TABLE rcvfrom( @ rcvid INTEGER PRIMARY KEY, -- Received-From ID @ uid INTEGER REFERENCES user, -- User login |
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** ******************************************************************************* ** ** This file contains code to implement the file transfer protocol. */ #include "config.h" #include "xfer.h" /* ** The aToken[0..nToken-1] blob array is a parse of a "file" line ** message. This routine finishes parsing that message and does ** a record insert of the file. ** ** The file line is in one of the following two forms: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 21 22 23 24 25 26 27 28 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 |
**
*******************************************************************************
**
** This file contains code to implement the file transfer protocol.
*/
#include "config.h"
#include "xfer.h"
/*
** Try to locate a record that is similar to rid and is a likely
** candidate for delta against rid. The similar record must be
** referenced in the onremote table.
**
** Return the integer record ID of the similar record. Or return
** 0 if none is found.
*/
static int similar_record(int rid, int traceFlag){
int inCnt, outCnt;
Stmt q;
int queue[100];
db_prepare(&q,
"SELECT srcid, EXISTS(SELECT 1 FROM onremote WHERE rid=srcid)"
" FROM delta"
" WHERE rid=:x"
" UNION ALL "
"SELECT rid, EXISTS(SELECT 1 FROM onremote WHERE rid=delta.rid)"
" FROM delta"
" WHERE srcid=:x"
);
queue[0] = rid;
inCnt = 1;
outCnt = 0;
while( outCnt<inCnt ){
int xid = queue[outCnt%64];
outCnt++;
db_bind_int(&q, ":x", xid);
if( traceFlag ) printf("xid=%d\n", xid);
while( db_step(&q)==SQLITE_ROW ){
int nid = db_column_int(&q, 0);
int hit = db_column_int(&q, 1);
if( traceFlag ) printf("nid=%d hit=%d\n", nid, hit);
if( hit ){
db_finalize(&q);
return nid;
}
if( inCnt<sizeof(queue)/sizeof(queue[0]) ){
int i;
for(i=0; i<inCnt && queue[i]!=nid; i++){}
if( i>=inCnt ){
queue[inCnt++] = nid;
}
}
}
db_reset(&q);
}
db_finalize(&q);
return 0;
}
/*
** COMMAND: test-similar-record
*/
void test_similar_record(void){
int i;
if( g.argc<4 ){
usage("SRC ONREMOTE...");
}
db_must_be_within_tree();
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
);
for(i=3; i<g.argc; i++){
int rid = name_to_rid(g.argv[i]);
printf("%s -> %d\n", g.argv[i], rid);
db_multi_exec("INSERT INTO onremote VALUES(%d)", rid);
}
printf("similar: %d\n", similar_record(name_to_rid(g.argv[2]), 1));
}
/*
** The aToken[0..nToken-1] blob array is a parse of a "file" line
** message. This routine finishes parsing that message and does
** a record insert of the file.
**
** The file line is in one of the following two forms:
|
| ︙ | ︙ | |||
85 86 87 88 89 90 91 |
**
** If pOut is not NULL, then append the text of the send message
** to pOut. Otherwise, append the text to the CGI output.
*/
static int send_file(int rid, Blob *pOut){
Blob content, uuid;
int size;
| < < < < < < < | < < < < < < < > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | > < < < < < < < < < < < < < < < < < < < < < | < | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
**
** If pOut is not NULL, then append the text of the send message
** to pOut. Otherwise, append the text to the CGI output.
*/
static int send_file(int rid, Blob *pOut){
Blob content, uuid;
int size;
int srcid;
blob_zero(&uuid);
db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid);
if( blob_size(&uuid)==0 ){
return 0;
}
content_get(rid, &content);
srcid = similar_record(rid, 0);
if( srcid ){
Blob src, delta;
Blob srcuuid;
content_get(srcid, &src);
blob_delta_create(&src, &content, &delta);
blob_reset(&src);
blob_reset(&content);
blob_zero(&srcuuid);
db_blob(&srcuuid, "SELECT uuid FROM blob WHERE rid=%d", srcid);
size = blob_size(&delta);
if( pOut ){
blob_appendf(pOut, "file %b %b %d\n", &uuid, &srcuuid, size);
blob_append(pOut, blob_buffer(&delta), size);
}else{
cgi_printf("file %b %b %d\n", &uuid, &srcuuid, size);
cgi_append_content(blob_buffer(&delta), size);
}
}else{
size = blob_size(&content);
if( pOut ){
blob_appendf(pOut, "file %b %d\n", &uuid, size);
blob_append(pOut, blob_buffer(&content), size);
}else{
cgi_printf("file %b %d\n", &uuid, size);
cgi_append_content(blob_buffer(&content), size);
}
blob_reset(&content);
blob_reset(&uuid);
}
db_multi_exec("INSERT OR IGNORE INTO onremote VALUES(%d)", rid);
return size;
}
/*
** Send all pending files.
*/
static int send_all_pending(Blob *pOut){
int iRidSent = 0;
int sent = 0;
int nSent = 0;
int maxSize = db_get_int("http-msg-size", 500000);
Stmt q;
db_prepare(&q, "SELECT rid FROM pending ORDER BY rid");
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q, 0);
if( sent<maxSize ){
sent += send_file(rid, pOut);
nSent++;
iRidSent = rid;
|
| ︙ | ︙ | |||
184 185 186 187 188 189 190 |
/* Delete the 'pending' records for all files just sent. Otherwise,
** we can wind up sending some files more than once.
*/
if( nSent>0 ){
db_multi_exec("DELETE FROM pending WHERE rid <= %d", iRidSent);
}
| < < < | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
/* Delete the 'pending' records for all files just sent. Otherwise,
** we can wind up sending some files more than once.
*/
if( nSent>0 ){
db_multi_exec("DELETE FROM pending WHERE rid <= %d", iRidSent);
}
return nSent;
}
/*
** Check the signature on an application/x-fossil payload received by
** the HTTP server. The signature is a line of the following form:
|
| ︙ | ︙ | |||
590 591 592 593 594 595 596 |
blob_appendf(&send, "leaf %s\n", zUuid);
nMsg++;
}
db_finalize(&q);
}
/* Exchange messages with the server */
| | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
blob_appendf(&send, "leaf %s\n", zUuid);
nMsg++;
}
db_finalize(&q);
}
/* Exchange messages with the server */
printf("Send: %3d files, %3d requests, %3d other msgs, %8d bytes\n",
nFile, nReq, nMsg, blob_size(&send));
nFileSend = nFile;
nFile = nReq = nMsg = 0;
http_exchange(&send, &recv);
blob_reset(&send);
/* Process the reply that came back from the server */
while( blob_line(&recv, &line) ){
|
| ︙ | ︙ | |||
702 703 704 705 706 707 708 |
}
if( blob_size(&errmsg) ){
fossil_fatal("%b", &errmsg);
}
blobarray_reset(aToken, nToken);
}
| < | | > | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
}
if( blob_size(&errmsg) ){
fossil_fatal("%b", &errmsg);
}
blobarray_reset(aToken, nToken);
}
printf("Received: %3d files, %3d requests, %3d other msgs, %8d bytes\n",
nFile, nReq, nMsg, blob_size(&recv));
blob_reset(&recv);
if( nFileSend + nFile==0 ){
nNoFileCycle++;
if( nNoFileCycle>1 ){
go = 0;
}
}else{
nNoFileCycle = 0;
|
| ︙ | ︙ |