summaryrefslogtreecommitdiff
path: root/xdelta3
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2013-01-20 08:57:36 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2013-01-20 08:57:36 +0000
commitdf1e90ee3c130ad7b89d2273c2b0d53cab42d6f1 (patch)
treea037af01cd708b90a597a0e6f0e3ad30127d5b45 /xdelta3
parent90e1af8f3e1867c33f86fe9ceccbaada01e8caef (diff)
Fix some TODOs (option_srcwinsz up to 4GB?
Diffstat (limited to 'xdelta3')
-rw-r--r--xdelta3/Makefile.am5
-rw-r--r--xdelta3/xdelta3-blkcache.h104
-rw-r--r--xdelta3/xdelta3-decode.h4
-rw-r--r--xdelta3/xdelta3-main.h5
-rw-r--r--xdelta3/xdelta3.c10
-rw-r--r--xdelta3/xdelta3.h6
6 files changed, 54 insertions, 80 deletions
diff --git a/xdelta3/Makefile.am b/xdelta3/Makefile.am
index 2b35e65..8283663 100644
--- a/xdelta3/Makefile.am
+++ b/xdelta3/Makefile.am
@@ -39,7 +39,7 @@ WFLAGS = -Wall -Wshadow -fno-builtin -Wextra -Wsign-compare \
39 -Wextra -Wno-unused-parameter 39 -Wextra -Wno-unused-parameter
40 40
41C_WFLAGS = $(WFLAGS) -pedantic -std=c99 41C_WFLAGS = $(WFLAGS) -pedantic -std=c99
42CXX_WFLAGS = $(WFLAGS) -pedantic 42CXX_WFLAGS = $(WFLAGS)
43 43
44common_CFLAGS = \ 44common_CFLAGS = \
45 -DGENERIC_ENCODE_TABLES=0 \ 45 -DGENERIC_ENCODE_TABLES=0 \
@@ -54,7 +54,8 @@ if DEBUG_SYMBOLS
54 common_CFLAGS += -g 54 common_CFLAGS += -g
55endif 55endif
56 56
57xdelta3_CFLAGS = $(C_WFLAGS) $(common_CFLAGS) -DXD3_DEBUG=1 57# For additional debugging, add -DXD3_DEBUG=1, 2, 3, ...
58xdelta3_CFLAGS = $(C_WFLAGS) $(common_CFLAGS) -DXD3_DEBUG=0
58xdelta3_LDADD = -lm 59xdelta3_LDADD = -lm
59 60
60xdelta3decode_CFLAGS = \ 61xdelta3decode_CFLAGS = \
diff --git a/xdelta3/xdelta3-blkcache.h b/xdelta3/xdelta3-blkcache.h
index e8a42a6..27263ed 100644
--- a/xdelta3/xdelta3-blkcache.h
+++ b/xdelta3/xdelta3-blkcache.h
@@ -1,6 +1,6 @@
1/* xdelta 3 - delta compression tools and library 1/* xdelta 3 - delta compression tools and library
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 * 2008, 2009, 2010 3 * 2008, 2009, 2010, 2011, 2012, 2013
4 * Joshua P. MacDonald 4 * Joshua P. MacDonald
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
@@ -18,9 +18,6 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21/* TODO: This code is heavily revised from 3.0z but still needs major
22 * refactoring. */
23
24#include "xdelta3-internal.h" 21#include "xdelta3-internal.h"
25 22
26typedef struct _main_blklru main_blklru; 23typedef struct _main_blklru main_blklru;
@@ -36,12 +33,13 @@ struct _main_blklru
36{ 33{
37 uint8_t *blk; 34 uint8_t *blk;
38 xoff_t blkno; 35 xoff_t blkno;
39 usize_t size; 36 xoff_t size;
40 main_blklru_list link; 37 main_blklru_list link;
41}; 38};
42 39
43#define MAX_LRU_SIZE 32U 40#define MAX_LRU_SIZE 32U
44#define XD3_MINSRCWINSZ (XD3_ALLOCSIZE * MAX_LRU_SIZE) 41#define XD3_MINSRCWINSZ (XD3_ALLOCSIZE * MAX_LRU_SIZE)
42#define XD3_MAXSRCWINSZ (1ULL << 32)
45 43
46XD3_MAKELIST(main_blklru_list,main_blklru,link); 44XD3_MAKELIST(main_blklru_list,main_blklru,link);
47 45
@@ -87,34 +85,25 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
87 main_file *sfile, xd3_source *source) 85 main_file *sfile, xd3_source *source)
88{ 86{
89 int ret = 0; 87 int ret = 0;
90 usize_t i; 88 int i;
91 xoff_t source_size = 0; 89 xoff_t source_size = 0;
92 usize_t blksize;
93 90
94 XD3_ASSERT (lru == NULL); 91 XD3_ASSERT (lru == NULL);
95 XD3_ASSERT (stream->src == NULL); 92 XD3_ASSERT (stream->src == NULL);
96 XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ); 93 XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ);
97 94
98 /* TODO: this code needs refactoring into FIFO, LRU, FAKE. Yuck!
99 * This is simplified from 3.0z which had issues with sizing the
100 * source buffer memory allocation and the source blocksize. */
101
102 /* LRU-specific */ 95 /* LRU-specific */
103 main_blklru_list_init (& lru_list); 96 main_blklru_list_init (& lru_list);
104 97
105 if (allow_fake_source) 98 if (allow_fake_source)
106 { 99 {
107 /* TODO: refactor
108 * TOOLS/recode-specific: Check "allow_fake_source" mode looks
109 * broken now. */
110 sfile->mode = XO_READ; 100 sfile->mode = XO_READ;
111 sfile->realname = sfile->filename; 101 sfile->realname = sfile->filename;
112 sfile->nread = 0; 102 sfile->nread = 0;
113 } 103 }
114 else 104 else
115 { 105 {
116 /* Either a regular file (possibly compressed) or a FIFO 106 /* Either a regular file or a FIFO. Both are possibly compressed. */
117 * (possibly compressed). */
118 if ((ret = main_file_open (sfile, sfile->filename, XO_READ))) 107 if ((ret = main_file_open (sfile, sfile->filename, XO_READ)))
119 { 108 {
120 return ret; 109 return ret;
@@ -152,22 +141,24 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
152 return ret; 141 return ret;
153 } 142 }
154 143
155 /* Main calls main_getblk_func() once before xd3_set_source(). This 144 /* Setup LRU blocks. */
156 * is the point at which external decompression may begin. Set the 145 for (i = MAX_LRU_SIZE - 1; i >= 0; --i)
157 * system for a single block. */ 146 {
158 lru_size = 1; 147 lru[i].blk = lru[0].blk + (option_srcwinsz / MAX_LRU_SIZE) * i;
159 lru[0].blkno = (xoff_t) -1; 148 lru[i].blkno = (xoff_t) -1;
160 blksize = option_srcwinsz; 149 lru[i].size = 0;
161 main_blklru_list_push_back (& lru_list, & lru[0]); 150 main_blklru_list_push_back (& lru_list, & lru[i]);
162 XD3_ASSERT (blksize != 0); 151 }
163 152
164 /* Initialize xd3_source. */ 153 /* Initialize xd3_source. */
165 source->blksize = blksize;
166 source->name = sfile->filename; 154 source->name = sfile->filename;
167 source->ioh = sfile; 155 source->ioh = sfile;
168 source->curblkno = (xoff_t) -1; 156 source->curblkno = (xoff_t) -1;
169 source->curblk = NULL; 157 source->curblk = NULL;
170 source->max_winsize = option_srcwinsz; 158 source->max_winsize = option_srcwinsz;
159 source->blksize = option_srcwinsz;
160
161 lru_size = 1;
171 162
172 if ((ret = main_getblk_func (stream, source, 0)) != 0) 163 if ((ret = main_getblk_func (stream, source, 0)) != 0)
173 { 164 {
@@ -177,44 +168,26 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
177 return ret; 168 return ret;
178 } 169 }
179 170
180 source->onblk = lru[0].size; /* xd3 sets onblk */ 171 /* If the file is smaller than the buffer, size is known. */
181 172 if (source->onblk < source->blksize)
182 /* If the file is smaller than a block, size is known. */
183 if (!sfile->size_known && source->onblk < blksize)
184 { 173 {
185 source_size = source->onblk; 174 source_size = source->onblk;
186 sfile->size_known = 1; 175 sfile->size_known = 1;
187 } 176 }
188 177 else
189 /* If the size is not known or is greater than the buffer size, we
190 * split the buffer across MAX_LRU_SIZE blocks (already allocated in
191 * "lru"). */
192 if (!sfile->size_known || source_size > option_srcwinsz)
193 { 178 {
194 /* Modify block 0, change blocksize. */ 179 /* Split the buffer */
195 blksize = option_srcwinsz / MAX_LRU_SIZE; 180 source->blksize = option_srcwinsz / MAX_LRU_SIZE;
196 source->blksize = blksize; 181 source->onblk = source->blksize;
197 source->onblk = blksize; /* xd3 sets onblk */
198 /* Note: source->max_winsize is unchanged. */
199 lru[0].size = blksize;
200 lru_size = MAX_LRU_SIZE; 182 lru_size = MAX_LRU_SIZE;
201 183
202 /* Setup rest of blocks. */ 184 for (i = 0; i < (int) MAX_LRU_SIZE; ++i)
203 for (i = 1; i < lru_size; i += 1)
204 { 185 {
205 lru[i].blk = lru[0].blk + (blksize * i);
206 lru[i].blkno = i; 186 lru[i].blkno = i;
207 lru[i].size = blksize; 187 lru[i].size = source->blksize;
208 main_blklru_list_push_back (& lru_list, & lru[i]);
209 } 188 }
210 } 189 }
211 190
212 if (! sfile->size_known)
213 {
214 /* If the size is not know, we must use FIFO discipline. */
215 do_src_fifo = 1;
216 }
217
218 /* Call the appropriate set_source method, handle errors, print 191 /* Call the appropriate set_source method, handle errors, print
219 * verbose message, etc. */ 192 * verbose message, etc. */
220 if (sfile->size_known) 193 if (sfile->size_known)
@@ -223,6 +196,8 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
223 } 196 }
224 else 197 else
225 { 198 {
199 /* If the size is not known, we must use FIFO discipline. */
200 do_src_fifo = 1;
226 ret = xd3_set_source (stream, source); 201 ret = xd3_set_source (stream, source);
227 } 202 }
228 203
@@ -233,7 +208,6 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
233 } 208 }
234 209
235 XD3_ASSERT (stream->src == source); 210 XD3_ASSERT (stream->src == source);
236 XD3_ASSERT (source->blksize == blksize);
237 211
238 if (option_verbose) 212 if (option_verbose)
239 { 213 {
@@ -264,7 +238,7 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd,
264 XPR(NT "source %s %s blksize %s window %s%s%s\n", 238 XPR(NT "source %s %s blksize %s window %s%s%s\n",
265 sfile->filename, 239 sfile->filename,
266 srcszbuf.buf, 240 srcszbuf.buf,
267 main_format_bcnt (blksize, &blkszbuf), 241 main_format_bcnt (source->blksize, &blkszbuf),
268 main_format_bcnt (option_srcwinsz, &winszbuf), 242 main_format_bcnt (option_srcwinsz, &winszbuf),
269 nbufs.buf, 243 nbufs.buf,
270 do_src_fifo ? " (FIFO)" : ""); 244 do_src_fifo ? " (FIFO)" : "");
@@ -333,6 +307,14 @@ main_getblk_lru (xd3_source *source, xoff_t blkno,
333 return 0; 307 return 0;
334} 308}
335 309
310/* Opens / seeks the source file and:
311 * (a) determines the source stream blocksize
312 * (b) determines the source file size (if possible)
313 * (c) calls main_read_primary_input (i.e., start external decompression)
314 *
315 * The main difficulty concerns an optimization: if the entire source
316 * fits inside the buffer, we decide to use a single block.
317 */
336static int 318static int
337main_read_seek_source (xd3_stream *stream, 319main_read_seek_source (xd3_stream *stream,
338 xd3_source *source, 320 xd3_source *source,
@@ -439,7 +421,7 @@ main_read_seek_source (xd3_stream *stream,
439 sfile->source_position += nread; 421 sfile->source_position += nread;
440 blru->size = nread; 422 blru->size = nread;
441 423
442 IF_DEBUG1 (DP(RINT "[getblk] skip blkno %"Q"u size %u\n", 424 IF_DEBUG1 (DP(RINT "[getblk] skip blkno %"Q"u size %"Q"u\n",
443 skip_blkno, blru->size)); 425 skip_blkno, blru->size));
444 426
445 XD3_ASSERT (sfile->source_position <= pos); 427 XD3_ASSERT (sfile->source_position <= pos);
@@ -467,7 +449,6 @@ main_getblk_func (xd3_stream *stream,
467 main_file *sfile = (main_file*) source->ioh; 449 main_file *sfile = (main_file*) source->ioh;
468 main_blklru *blru; 450 main_blklru *blru;
469 int is_new; 451 int is_new;
470 int did_seek = 0;
471 size_t nread = 0; 452 size_t nread = 0;
472 453
473 if (allow_fake_source) 454 if (allow_fake_source)
@@ -505,19 +486,14 @@ main_getblk_func (xd3_stream *stream,
505 return ret; 486 return ret;
506 } 487 }
507 488
508 /* Indicates that another call to main_getblk_lru() may be 489 if ((ret = main_getblk_lru (source, blkno, & blru, & is_new)))
509 * needed */ 490 {
510 did_seek = 1; 491 return ret;
492 }
511 } 493 }
512 494
513 XD3_ASSERT (sfile->source_position == pos); 495 XD3_ASSERT (sfile->source_position == pos);
514 496
515 if (did_seek &&
516 (ret = main_getblk_lru (source, blkno, & blru, & is_new)))
517 {
518 return ret;
519 }
520
521 if ((ret = main_read_primary_input (sfile, 497 if ((ret = main_read_primary_input (sfile,
522 (uint8_t*) blru->blk, 498 (uint8_t*) blru->blk,
523 source->blksize, 499 source->blksize,
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h
index c0cb578..f867055 100644
--- a/xdelta3/xdelta3-decode.h
+++ b/xdelta3/xdelta3-decode.h
@@ -454,7 +454,7 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
454 (blkoff + take > source->onblk)) 454 (blkoff + take > source->onblk))
455 { 455 {
456 IF_DEBUG1 (XPR(NT "[srcfile] short at blkno %"Q"u onblk " 456 IF_DEBUG1 (XPR(NT "[srcfile] short at blkno %"Q"u onblk "
457 "%u blksize %u blkoff %u take %u\n", 457 "%"Q"u blksize %u blkoff %u take %u\n",
458 block, 458 block,
459 source->onblk, 459 source->onblk,
460 blksize, 460 blksize,
@@ -1096,7 +1096,7 @@ xd3_decode_input (xd3_stream *stream)
1096 "decode cpyoff %"Q"u " 1096 "decode cpyoff %"Q"u "
1097 "cpyblkno %"Q"u " 1097 "cpyblkno %"Q"u "
1098 "cpyblkoff %u " 1098 "cpyblkoff %u "
1099 "blksize %u\n", 1099 "blksize %"Q"u\n",
1100 stream->dec_cpyoff, 1100 stream->dec_cpyoff,
1101 src->cpyoff_blocks, 1101 src->cpyoff_blocks,
1102 src->cpyoff_blkoff, 1102 src->cpyoff_blkoff,
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h
index 126271f..3ae24cd 100644
--- a/xdelta3/xdelta3-main.h
+++ b/xdelta3/xdelta3-main.h
@@ -296,9 +296,6 @@ static main_extcomp extcomp_types[] =
296 { "gzip", "-c", "gzip", "-dc", "G", "\037\213", 2, 0 }, 296 { "gzip", "-c", "gzip", "-dc", "G", "\037\213", 2, 0 },
297 { "compress", "-c", "uncompress", "-c", "Z", "\037\235", 2, 0 }, 297 { "compress", "-c", "uncompress", "-c", "Z", "\037\235", 2, 0 },
298 298
299 /* TODO: add commandline support for magic-less formats */
300 /*{ "lzma", "-c", "lzma", "-dc", "M", "]\000", 2, 0 },*/
301
302 /* Xz is lzma with a magic number http://tukaani.org/xz/ */ 299 /* Xz is lzma with a magic number http://tukaani.org/xz/ */
303 { "xz", "-c", "xz", "-dc", "Y", "\xfd\x37\x7a\x58\x5a\x00", 2, 0 }, 300 { "xz", "-c", "xz", "-dc", "Y", "\xfd\x37\x7a\x58\x5a\x00", 2, 0 },
304}; 301};
@@ -3776,7 +3773,7 @@ int main (int argc, char **argv)
3776 case 'B': { 3773 case 'B': {
3777 xoff_t bsize; 3774 xoff_t bsize;
3778 if ((ret = main_atoux (my_optarg, & bsize, 3775 if ((ret = main_atoux (my_optarg, & bsize,
3779 XD3_MINSRCWINSZ, 0, 'B'))) 3776 XD3_MINSRCWINSZ, XD3_MAXSRCWINSZ, 'B')))
3780 { 3777 {
3781 goto exit; 3778 goto exit;
3782 } 3779 }
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c
index 608622a..c22c763 100644
--- a/xdelta3/xdelta3.c
+++ b/xdelta3/xdelta3.c
@@ -1529,10 +1529,10 @@ xd3_swap_usize_t (usize_t* p1, usize_t* p2)
1529 1529
1530/* It's not constant time, but it computes the log. */ 1530/* It's not constant time, but it computes the log. */
1531static int 1531static int
1532xd3_check_pow2 (xoff_t value, usize_t *logof) 1532xd3_check_pow2 (xoff_t value, int *logof)
1533{ 1533{
1534 xoff_t x = 1; 1534 xoff_t x = 1;
1535 usize_t nolog; 1535 int nolog;
1536 if (logof == NULL) { 1536 if (logof == NULL) {
1537 logof = &nolog; 1537 logof = &nolog;
1538 } 1538 }
@@ -2653,7 +2653,7 @@ int
2653xd3_set_source (xd3_stream *stream, 2653xd3_set_source (xd3_stream *stream,
2654 xd3_source *src) 2654 xd3_source *src)
2655{ 2655{
2656 usize_t shiftby; 2656 int shiftby;
2657 2657
2658 stream->src = src; 2658 stream->src = src;
2659 src->srclen = 0; 2659 src->srclen = 0;
@@ -2665,7 +2665,7 @@ xd3_set_source (xd3_stream *stream,
2665 { 2665 {
2666 src->blksize = xd3_pow2_roundup(src->blksize); 2666 src->blksize = xd3_pow2_roundup(src->blksize);
2667 xd3_check_pow2 (src->blksize, &shiftby); 2667 xd3_check_pow2 (src->blksize, &shiftby);
2668 IF_DEBUG1 (DP(RINT "raising src_blksz to %u\n", src->blksize)); 2668 IF_DEBUG1 (DP(RINT "raising src_blksz to %"Q"u\n", src->blksize));
2669 } 2669 }
2670 2670
2671 src->shiftby = shiftby; 2671 src->shiftby = shiftby;
@@ -2674,7 +2674,7 @@ xd3_set_source (xd3_stream *stream,
2674 if (xd3_check_pow2 (src->max_winsize, NULL) != 0) 2674 if (xd3_check_pow2 (src->max_winsize, NULL) != 0)
2675 { 2675 {
2676 src->max_winsize = xd3_xoff_roundup(src->max_winsize); 2676 src->max_winsize = xd3_xoff_roundup(src->max_winsize);
2677 IF_DEBUG1 (DP(RINT "raising src_maxsize to %u\n", src->blksize)); 2677 IF_DEBUG1 (DP(RINT "raising src_maxsize to %"Q"u\n", src->blksize));
2678 } 2678 }
2679 src->max_winsize = max(src->max_winsize, XD3_ALLOCSIZE); 2679 src->max_winsize = max(src->max_winsize, XD3_ALLOCSIZE);
2680 2680
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h
index 686e05c..66def15 100644
--- a/xdelta3/xdelta3.h
+++ b/xdelta3/xdelta3.h
@@ -718,7 +718,7 @@ struct _xd3_config
718struct _xd3_source 718struct _xd3_source
719{ 719{
720 /* you set */ 720 /* you set */
721 usize_t blksize; /* block size */ 721 xoff_t blksize; /* block size */
722 const char *name; /* its name, for debug/print 722 const char *name; /* its name, for debug/print
723 purposes */ 723 purposes */
724 void *ioh; /* opaque handle */ 724 void *ioh; /* opaque handle */
@@ -727,14 +727,14 @@ struct _xd3_source
727 /* getblk sets */ 727 /* getblk sets */
728 xoff_t curblkno; /* current block number: client 728 xoff_t curblkno; /* current block number: client
729 sets after getblk request */ 729 sets after getblk request */
730 usize_t onblk; /* number of bytes on current 730 xoff_t onblk; /* number of bytes on current
731 block: client sets, must be >= 0 731 block: client sets, must be >= 0
732 and <= blksize */ 732 and <= blksize */
733 const uint8_t *curblk; /* current block array: client 733 const uint8_t *curblk; /* current block array: client
734 sets after getblk request */ 734 sets after getblk request */
735 735
736 /* xd3 sets */ 736 /* xd3 sets */
737 usize_t srclen; /* length of this source window */ 737 usize_t srclen; /* length of this source window */
738 xoff_t srcbase; /* offset of this source window 738 xoff_t srcbase; /* offset of this source window
739 in the source itself */ 739 in the source itself */
740 int shiftby; /* for power-of-two blocksizes */ 740 int shiftby; /* for power-of-two blocksizes */