diff options
Diffstat (limited to 'xdelta3/xdelta3-blkcache.h')
-rw-r--r-- | xdelta3/xdelta3-blkcache.h | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/xdelta3/xdelta3-blkcache.h b/xdelta3/xdelta3-blkcache.h index a68a59a..82d720e 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, 2011, 2012, 2013 | 3 | * 2008, 2009, 2010 |
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,6 +18,9 @@ | |||
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 | |||
21 | #include "xdelta3-internal.h" | 24 | #include "xdelta3-internal.h" |
22 | 25 | ||
23 | typedef struct _main_blklru main_blklru; | 26 | typedef struct _main_blklru main_blklru; |
@@ -33,13 +36,13 @@ struct _main_blklru | |||
33 | { | 36 | { |
34 | uint8_t *blk; | 37 | uint8_t *blk; |
35 | xoff_t blkno; | 38 | xoff_t blkno; |
36 | xoff_t size; | 39 | usize_t size; |
37 | main_blklru_list link; | 40 | main_blklru_list link; |
38 | }; | 41 | }; |
39 | 42 | ||
40 | #define MAX_LRU_SIZE 32U | 43 | #define MAX_LRU_SIZE 32U |
41 | #define XD3_MINSRCWINSZ (XD3_ALLOCSIZE * MAX_LRU_SIZE) | 44 | #define XD3_MINSRCWINSZ (XD3_ALLOCSIZE * MAX_LRU_SIZE) |
42 | #define XD3_MAXSRCWINSZ (1ULL << 32) | 45 | #define XD3_MAXSRCWINSZ (1ULL << 31) |
43 | 46 | ||
44 | XD3_MAKELIST(main_blklru_list,main_blklru,link); | 47 | XD3_MAKELIST(main_blklru_list,main_blklru,link); |
45 | 48 | ||
@@ -87,23 +90,32 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
87 | int ret = 0; | 90 | int ret = 0; |
88 | usize_t i; | 91 | usize_t i; |
89 | xoff_t source_size = 0; | 92 | xoff_t source_size = 0; |
93 | usize_t blksize; | ||
90 | 94 | ||
91 | XD3_ASSERT (lru == NULL); | 95 | XD3_ASSERT (lru == NULL); |
92 | XD3_ASSERT (stream->src == NULL); | 96 | XD3_ASSERT (stream->src == NULL); |
93 | XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ); | 97 | XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ); |
94 | 98 | ||
99 | /* TODO: this code needs refactoring into FIFO, LRU, FAKE. Yuck! | ||
100 | * This is simplified from 3.0z which had issues with sizing the | ||
101 | * source buffer memory allocation and the source blocksize. */ | ||
102 | |||
95 | /* LRU-specific */ | 103 | /* LRU-specific */ |
96 | main_blklru_list_init (& lru_list); | 104 | main_blklru_list_init (& lru_list); |
97 | 105 | ||
98 | if (allow_fake_source) | 106 | if (allow_fake_source) |
99 | { | 107 | { |
108 | /* TODO: refactor | ||
109 | * TOOLS/recode-specific: Check "allow_fake_source" mode looks | ||
110 | * broken now. */ | ||
100 | sfile->mode = XO_READ; | 111 | sfile->mode = XO_READ; |
101 | sfile->realname = sfile->filename; | 112 | sfile->realname = sfile->filename; |
102 | sfile->nread = 0; | 113 | sfile->nread = 0; |
103 | } | 114 | } |
104 | else | 115 | else |
105 | { | 116 | { |
106 | /* Either a regular file or a FIFO. Both are possibly compressed. */ | 117 | /* Either a regular file (possibly compressed) or a FIFO |
118 | * (possibly compressed). */ | ||
107 | if ((ret = main_file_open (sfile, sfile->filename, XO_READ))) | 119 | if ((ret = main_file_open (sfile, sfile->filename, XO_READ))) |
108 | { | 120 | { |
109 | return ret; | 121 | return ret; |
@@ -141,24 +153,22 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
141 | return ret; | 153 | return ret; |
142 | } | 154 | } |
143 | 155 | ||
144 | /* Setup LRU blocks. */ | 156 | /* Main calls main_getblk_func() once before xd3_set_source(). This |
145 | for (i = 0; i < MAX_LRU_SIZE; i++) | 157 | * is the point at which external decompression may begin. Set the |
146 | { | 158 | * system for a single block. */ |
147 | lru[i].blk = lru[0].blk + (option_srcwinsz / MAX_LRU_SIZE) * i; | 159 | lru_size = 1; |
148 | lru[i].blkno = (xoff_t) -1; | 160 | lru[0].blkno = (xoff_t) -1; |
149 | lru[i].size = 0; | 161 | blksize = option_srcwinsz; |
150 | main_blklru_list_push_back (& lru_list, & lru[i]); | 162 | main_blklru_list_push_back (& lru_list, & lru[0]); |
151 | } | 163 | XD3_ASSERT (blksize != 0); |
152 | 164 | ||
153 | /* Initialize xd3_source. */ | 165 | /* Initialize xd3_source. */ |
166 | source->blksize = blksize; | ||
154 | source->name = sfile->filename; | 167 | source->name = sfile->filename; |
155 | source->ioh = sfile; | 168 | source->ioh = sfile; |
156 | source->curblkno = (xoff_t) -1; | 169 | source->curblkno = (xoff_t) -1; |
157 | source->curblk = NULL; | 170 | source->curblk = NULL; |
158 | source->max_winsize = option_srcwinsz; | 171 | source->max_winsize = option_srcwinsz; |
159 | source->blksize = option_srcwinsz; | ||
160 | |||
161 | lru_size = 1; | ||
162 | 172 | ||
163 | if ((ret = main_getblk_func (stream, source, 0)) != 0) | 173 | if ((ret = main_getblk_func (stream, source, 0)) != 0) |
164 | { | 174 | { |
@@ -168,26 +178,44 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
168 | return ret; | 178 | return ret; |
169 | } | 179 | } |
170 | 180 | ||
171 | /* If the file is smaller than the buffer, size is known. */ | 181 | source->onblk = lru[0].size; /* xd3 sets onblk */ |
172 | if (source->onblk < source->blksize) | 182 | |
183 | /* If the file is smaller than a block, size is known. */ | ||
184 | if (!sfile->size_known && source->onblk < blksize) | ||
173 | { | 185 | { |
174 | source_size = source->onblk; | 186 | source_size = source->onblk; |
175 | sfile->size_known = 1; | 187 | sfile->size_known = 1; |
176 | } | 188 | } |
177 | else | 189 | |
190 | /* If the size is not known or is greater than the buffer size, we | ||
191 | * split the buffer across MAX_LRU_SIZE blocks (already allocated in | ||
192 | * "lru"). */ | ||
193 | if (!sfile->size_known || source_size > option_srcwinsz) | ||
178 | { | 194 | { |
179 | /* Split the buffer */ | 195 | /* Modify block 0, change blocksize. */ |
180 | source->blksize = option_srcwinsz / MAX_LRU_SIZE; | 196 | blksize = option_srcwinsz / MAX_LRU_SIZE; |
181 | source->onblk = source->blksize; | 197 | source->blksize = blksize; |
198 | source->onblk = blksize; /* xd3 sets onblk */ | ||
199 | /* Note: source->max_winsize is unchanged. */ | ||
200 | lru[0].size = blksize; | ||
182 | lru_size = MAX_LRU_SIZE; | 201 | lru_size = MAX_LRU_SIZE; |
183 | 202 | ||
184 | for (i = 0; i < (int) MAX_LRU_SIZE; ++i) | 203 | /* Setup rest of blocks. */ |
204 | for (i = 1; i < lru_size; i += 1) | ||
185 | { | 205 | { |
206 | lru[i].blk = lru[0].blk + (blksize * i); | ||
186 | lru[i].blkno = i; | 207 | lru[i].blkno = i; |
187 | lru[i].size = source->blksize; | 208 | lru[i].size = blksize; |
209 | main_blklru_list_push_back (& lru_list, & lru[i]); | ||
188 | } | 210 | } |
189 | } | 211 | } |
190 | 212 | ||
213 | if (! sfile->size_known) | ||
214 | { | ||
215 | /* If the size is not know, we must use FIFO discipline. */ | ||
216 | do_src_fifo = 1; | ||
217 | } | ||
218 | |||
191 | /* Call the appropriate set_source method, handle errors, print | 219 | /* Call the appropriate set_source method, handle errors, print |
192 | * verbose message, etc. */ | 220 | * verbose message, etc. */ |
193 | if (sfile->size_known) | 221 | if (sfile->size_known) |
@@ -196,8 +224,6 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
196 | } | 224 | } |
197 | else | 225 | else |
198 | { | 226 | { |
199 | /* If the size is not known, we must use FIFO discipline. */ | ||
200 | do_src_fifo = 1; | ||
201 | ret = xd3_set_source (stream, source); | 227 | ret = xd3_set_source (stream, source); |
202 | } | 228 | } |
203 | 229 | ||
@@ -208,6 +234,7 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
208 | } | 234 | } |
209 | 235 | ||
210 | XD3_ASSERT (stream->src == source); | 236 | XD3_ASSERT (stream->src == source); |
237 | XD3_ASSERT (source->blksize == blksize); | ||
211 | 238 | ||
212 | if (option_verbose) | 239 | if (option_verbose) |
213 | { | 240 | { |
@@ -238,7 +265,7 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
238 | XPR(NT "source %s %s blksize %s window %s%s%s\n", | 265 | XPR(NT "source %s %s blksize %s window %s%s%s\n", |
239 | sfile->filename, | 266 | sfile->filename, |
240 | srcszbuf.buf, | 267 | srcszbuf.buf, |
241 | main_format_bcnt (source->blksize, &blkszbuf), | 268 | main_format_bcnt (blksize, &blkszbuf), |
242 | main_format_bcnt (option_srcwinsz, &winszbuf), | 269 | main_format_bcnt (option_srcwinsz, &winszbuf), |
243 | nbufs.buf, | 270 | nbufs.buf, |
244 | do_src_fifo ? " (FIFO)" : ""); | 271 | do_src_fifo ? " (FIFO)" : ""); |
@@ -303,18 +330,10 @@ main_getblk_lru (xd3_source *source, xoff_t blkno, | |||
303 | lru_filled += 1; | 330 | lru_filled += 1; |
304 | (*is_new) = 1; | 331 | (*is_new) = 1; |
305 | (*blrup) = blru; | 332 | (*blrup) = blru; |
306 | blru->blkno = (xoff_t) -1; | 333 | blru->blkno = -1; |
307 | return 0; | 334 | return 0; |
308 | } | 335 | } |
309 | 336 | ||
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 | */ | ||
318 | static int | 337 | static int |
319 | main_read_seek_source (xd3_stream *stream, | 338 | main_read_seek_source (xd3_stream *stream, |
320 | xd3_source *source, | 339 | xd3_source *source, |
@@ -384,7 +403,7 @@ main_read_seek_source (xd3_stream *stream, | |||
384 | while (sfile->source_position < pos) | 403 | while (sfile->source_position < pos) |
385 | { | 404 | { |
386 | xoff_t skip_blkno; | 405 | xoff_t skip_blkno; |
387 | xoff_t skip_offset; | 406 | usize_t skip_offset; |
388 | 407 | ||
389 | xd3_blksize_div (sfile->source_position, source, | 408 | xd3_blksize_div (sfile->source_position, source, |
390 | &skip_blkno, &skip_offset); | 409 | &skip_blkno, &skip_offset); |
@@ -421,7 +440,7 @@ main_read_seek_source (xd3_stream *stream, | |||
421 | sfile->source_position += nread; | 440 | sfile->source_position += nread; |
422 | blru->size = nread; | 441 | blru->size = nread; |
423 | 442 | ||
424 | IF_DEBUG1 (DP(RINT "[getblk] skip blkno %"Q"u size %"Q"u\n", | 443 | IF_DEBUG1 (DP(RINT "[getblk] skip blkno %"Q"u size %u\n", |
425 | skip_blkno, blru->size)); | 444 | skip_blkno, blru->size)); |
426 | 445 | ||
427 | XD3_ASSERT (sfile->source_position <= pos); | 446 | XD3_ASSERT (sfile->source_position <= pos); |
@@ -449,6 +468,7 @@ main_getblk_func (xd3_stream *stream, | |||
449 | main_file *sfile = (main_file*) source->ioh; | 468 | main_file *sfile = (main_file*) source->ioh; |
450 | main_blklru *blru; | 469 | main_blklru *blru; |
451 | int is_new; | 470 | int is_new; |
471 | int did_seek = 0; | ||
452 | size_t nread = 0; | 472 | size_t nread = 0; |
453 | 473 | ||
454 | if (allow_fake_source) | 474 | if (allow_fake_source) |
@@ -486,14 +506,19 @@ main_getblk_func (xd3_stream *stream, | |||
486 | return ret; | 506 | return ret; |
487 | } | 507 | } |
488 | 508 | ||
489 | if ((ret = main_getblk_lru (source, blkno, & blru, & is_new))) | 509 | /* Indicates that another call to main_getblk_lru() may be |
490 | { | 510 | * needed */ |
491 | return ret; | 511 | did_seek = 1; |
492 | } | ||
493 | } | 512 | } |
494 | 513 | ||
495 | XD3_ASSERT (sfile->source_position == pos); | 514 | XD3_ASSERT (sfile->source_position == pos); |
496 | 515 | ||
516 | if (did_seek && | ||
517 | (ret = main_getblk_lru (source, blkno, & blru, & is_new))) | ||
518 | { | ||
519 | return ret; | ||
520 | } | ||
521 | |||
497 | if ((ret = main_read_primary_input (sfile, | 522 | if ((ret = main_read_primary_input (sfile, |
498 | (uint8_t*) blru->blk, | 523 | (uint8_t*) blru->blk, |
499 | source->blksize, | 524 | source->blksize, |