summaryrefslogtreecommitdiff
path: root/xdelta3/xdelta3-blkcache.h
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3/xdelta3-blkcache.h')
-rw-r--r--xdelta3/xdelta3-blkcache.h107
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
23typedef struct _main_blklru main_blklru; 26typedef 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
44XD3_MAKELIST(main_blklru_list,main_blklru,link); 47XD3_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 */
318static int 337static int
319main_read_seek_source (xd3_stream *stream, 338main_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,