diff options
-rw-r--r-- | xdelta3/Makefile | 2 | ||||
-rw-r--r-- | xdelta3/xdelta3-decode.h | 4 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 296 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 8 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 7 |
5 files changed, 174 insertions, 143 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile index 6826253..5024b4f 100644 --- a/xdelta3/Makefile +++ b/xdelta3/Makefile | |||
@@ -170,7 +170,7 @@ xdelta3-32: $(SOURCES) | |||
170 | xdelta3-debug2: $(SOURCES) | 170 | xdelta3-debug2: $(SOURCES) |
171 | $(CC) -g $(CFLAGS) \ | 171 | $(CC) -g $(CFLAGS) \ |
172 | xdelta3.c -o xdelta3-debug2 \ | 172 | xdelta3.c -o xdelta3-debug2 \ |
173 | -DXD3_DEBUG=2 \ | 173 | -DXD3_DEBUG=3 \ |
174 | -DXD3_MAIN=1 \ | 174 | -DXD3_MAIN=1 \ |
175 | -DXD3_POSIX=1 \ | 175 | -DXD3_POSIX=1 \ |
176 | -DXD3_USE_LARGEFILE64=1 \ | 176 | -DXD3_USE_LARGEFILE64=1 \ |
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h index cc0a0e7..cc33d5a 100644 --- a/xdelta3/xdelta3-decode.h +++ b/xdelta3/xdelta3-decode.h | |||
@@ -631,9 +631,7 @@ xd3_decode_sections (xd3_stream *stream) | |||
631 | 631 | ||
632 | /* OPT: A possible optimization is to avoid allocating memory in | 632 | /* OPT: A possible optimization is to avoid allocating memory in |
633 | * decode_setup_buffers and to avoid a large memcpy when the window | 633 | * decode_setup_buffers and to avoid a large memcpy when the window |
634 | * consists of a single VCD_SOURCE copy instruction. The only | 634 | * consists of a single VCD_SOURCE copy instruction. */ |
635 | * potential problem is if the following window is a VCD_TARGET, | ||
636 | * then you need to remember... */ | ||
637 | if ((ret = xd3_decode_setup_buffers (stream))) { return ret; } | 635 | if ((ret = xd3_decode_setup_buffers (stream))) { return ret; } |
638 | 636 | ||
639 | return 0; | 637 | return 0; |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 6ea6c68..df55ade 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -224,8 +224,10 @@ struct _main_file | |||
224 | xoff_t nread; /* for input position */ | 224 | xoff_t nread; /* for input position */ |
225 | xoff_t nwrite; /* for output position */ | 225 | xoff_t nwrite; /* for output position */ |
226 | uint8_t *snprintf_buf; /* internal snprintf() use */ | 226 | uint8_t *snprintf_buf; /* internal snprintf() use */ |
227 | xoff_t source_position; /* for avoiding seek in getblk_func */ | 227 | int size_known; /* Set by main_set_souze */ |
228 | xoff_t source_position; /* for avoiding seek in getblk_func */ | ||
228 | int seek_failed; /* after seek fails once */ | 229 | int seek_failed; /* after seek fails once */ |
230 | const char *decode_cmdname; /* for verbose output */ | ||
229 | }; | 231 | }; |
230 | 232 | ||
231 | /* Various strings and magic values used to detect and call external | 233 | /* Various strings and magic values used to detect and call external |
@@ -255,13 +257,14 @@ struct _main_blklru_list | |||
255 | 257 | ||
256 | struct _main_blklru | 258 | struct _main_blklru |
257 | { | 259 | { |
258 | uint8_t *blk; | 260 | uint8_t *blk; |
259 | xoff_t blkno; | 261 | xoff_t blkno; |
260 | usize_t size; | 262 | usize_t size; |
261 | main_blklru_list link; | 263 | main_blklru_list link; |
262 | }; | 264 | }; |
263 | 265 | ||
264 | #define LRU_SIZE 32U | 266 | #define MAX_LRU_SIZE 32U |
267 | #define MIN_LRU_SIZE 1U | ||
265 | #define XD3_MINSRCWINSZ XD3_ALLOCSIZE | 268 | #define XD3_MINSRCWINSZ XD3_ALLOCSIZE |
266 | 269 | ||
267 | /* ... represented as a list (no cache index). */ | 270 | /* ... represented as a list (no cache index). */ |
@@ -478,7 +481,7 @@ main_malloc1 (usize_t size) | |||
478 | { | 481 | { |
479 | void* r = malloc (size); | 482 | void* r = malloc (size); |
480 | if (r == NULL) { XPR(NT "malloc: %s\n", xd3_mainerror (ENOMEM)); } | 483 | if (r == NULL) { XPR(NT "malloc: %s\n", xd3_mainerror (ENOMEM)); } |
481 | else if (option_verbose > 3) { XPR(NT "malloc: %u: %p\n", size, r); } | 484 | else if (option_verbose > 4) { XPR(NT "malloc: %u: %p\n", size, r); } |
482 | return r; | 485 | return r; |
483 | } | 486 | } |
484 | 487 | ||
@@ -501,7 +504,7 @@ main_alloc (void *opaque, | |||
501 | static void | 504 | static void |
502 | main_free1 (void *opaque, void *ptr) | 505 | main_free1 (void *opaque, void *ptr) |
503 | { | 506 | { |
504 | if (option_verbose > 3) { XPR(NT "free: %p\n", ptr); } | 507 | if (option_verbose > 4) { XPR(NT "free: %p\n", ptr); } |
505 | free (ptr); | 508 | free (ptr); |
506 | } | 509 | } |
507 | 510 | ||
@@ -1030,7 +1033,7 @@ main_file_read (main_file *ifile, | |||
1030 | } | 1033 | } |
1031 | else | 1034 | else |
1032 | { | 1035 | { |
1033 | if (option_verbose > 3) { XPR(NT "main read: %s: %u\n", | 1036 | if (option_verbose > 3) { XPR(NT "read %s: %u bytes\n", |
1034 | ifile->filename, (*nread)); } | 1037 | ifile->filename, (*nread)); } |
1035 | ifile->nread += (*nread); | 1038 | ifile->nread += (*nread); |
1036 | } | 1039 | } |
@@ -1071,7 +1074,7 @@ main_file_write (main_file *ofile, uint8_t *buf, usize_t size, const char *msg) | |||
1071 | } | 1074 | } |
1072 | else | 1075 | else |
1073 | { | 1076 | { |
1074 | if (option_verbose > 3) { XPR(NT "main write: %s: %u\n", | 1077 | if (option_verbose > 4) { XPR(NT "write %s: %u bytes\n", |
1075 | ofile->filename, size); } | 1078 | ofile->filename, size); } |
1076 | ofile->nwrite += size; | 1079 | ofile->nwrite += size; |
1077 | } | 1080 | } |
@@ -1139,32 +1142,6 @@ main_write_output (xd3_stream* stream, main_file *ofile) | |||
1139 | return 0; | 1142 | return 0; |
1140 | } | 1143 | } |
1141 | 1144 | ||
1142 | /* Called when the stream transitions from unknown status to | ||
1143 | * possibly/definitely non-seekable. */ | ||
1144 | static void | ||
1145 | main_internal_do_not_lru () | ||
1146 | { | ||
1147 | usize_t i; | ||
1148 | |||
1149 | if (do_not_lru) | ||
1150 | { | ||
1151 | /* Already set */ | ||
1152 | return; | ||
1153 | } | ||
1154 | |||
1155 | do_not_lru = 1; | ||
1156 | |||
1157 | /* It's possible that we've already ejected in a non-LRU fashion, | ||
1158 | * report on that. */ | ||
1159 | for (i = 0; i < lru_size; i += 1) | ||
1160 | { | ||
1161 | if (lru[i].blkno == (xoff_t) -1) | ||
1162 | { | ||
1163 | continue; | ||
1164 | } | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | static int | 1145 | static int |
1169 | main_set_secondary_flags (xd3_config *config) | 1146 | main_set_secondary_flags (xd3_config *config) |
1170 | { | 1147 | { |
@@ -2347,10 +2324,10 @@ main_input_decompress_setup (const main_extcomp *decomp, | |||
2347 | * is passed to the pipe copier. This avoids using the same size | 2324 | * is passed to the pipe copier. This avoids using the same size |
2348 | * buffer in both cases. */ | 2325 | * buffer in both cases. */ |
2349 | static int | 2326 | static int |
2350 | main_secondary_decompress_check (main_file *ifile, | 2327 | main_secondary_decompress_check (main_file *file, |
2351 | uint8_t *input_buf, | 2328 | uint8_t *input_buf, |
2352 | usize_t input_size, | 2329 | usize_t input_size, |
2353 | usize_t *nread) | 2330 | usize_t *nread) |
2354 | { | 2331 | { |
2355 | int ret; | 2332 | int ret; |
2356 | usize_t i; | 2333 | usize_t i; |
@@ -2358,7 +2335,7 @@ main_secondary_decompress_check (main_file *ifile, | |||
2358 | usize_t check_nread; | 2335 | usize_t check_nread; |
2359 | uint8_t check_buf[XD3_ALLOCSIZE]; /* TODO: stack limit */ | 2336 | uint8_t check_buf[XD3_ALLOCSIZE]; /* TODO: stack limit */ |
2360 | 2337 | ||
2361 | if ((ret = main_file_read (ifile, check_buf, | 2338 | if ((ret = main_file_read (file, check_buf, |
2362 | try_read, | 2339 | try_read, |
2363 | & check_nread, "input read failed"))) | 2340 | & check_nread, "input read failed"))) |
2364 | { | 2341 | { |
@@ -2373,20 +2350,11 @@ main_secondary_decompress_check (main_file *ifile, | |||
2373 | /* The following expr skips decompression if we are trying | 2350 | /* The following expr skips decompression if we are trying |
2374 | * to read a VCDIFF input and that is the magic number. */ | 2351 | * to read a VCDIFF input and that is the magic number. */ |
2375 | !((decomp->flags & RD_NONEXTERNAL) && | 2352 | !((decomp->flags & RD_NONEXTERNAL) && |
2376 | (ifile->flags & RD_NONEXTERNAL)) && | 2353 | (file->flags & RD_NONEXTERNAL)) && |
2377 | memcmp (check_buf, decomp->magic, decomp->magic_size) == 0) | 2354 | memcmp (check_buf, decomp->magic, decomp->magic_size) == 0) |
2378 | { | 2355 | { |
2379 | if (! option_quiet) | 2356 | file->size_known = 0; |
2380 | { | 2357 | return main_input_decompress_setup (decomp, file, |
2381 | XPR(NT "%s | %s %s\n", | ||
2382 | ifile->filename, | ||
2383 | decomp->decomp_cmdname, | ||
2384 | decomp->decomp_options); | ||
2385 | } | ||
2386 | |||
2387 | main_internal_do_not_lru (); | ||
2388 | |||
2389 | return main_input_decompress_setup (decomp, ifile, | ||
2390 | input_buf, input_size, | 2358 | input_buf, input_size, |
2391 | check_buf, XD3_ALLOCSIZE, | 2359 | check_buf, XD3_ALLOCSIZE, |
2392 | check_nread, nread); | 2360 | check_nread, nread); |
@@ -2398,7 +2366,7 @@ main_secondary_decompress_check (main_file *ifile, | |||
2398 | 2366 | ||
2399 | if (check_nread == try_read) | 2367 | if (check_nread == try_read) |
2400 | { | 2368 | { |
2401 | ret = main_file_read (ifile, | 2369 | ret = main_file_read (file, |
2402 | input_buf + try_read, | 2370 | input_buf + try_read, |
2403 | input_size - try_read, | 2371 | input_size - try_read, |
2404 | nread, | 2372 | nread, |
@@ -2799,7 +2767,7 @@ main_open_output (xd3_stream *stream, main_file *ofile) | |||
2799 | return ret; | 2767 | return ret; |
2800 | } | 2768 | } |
2801 | 2769 | ||
2802 | if (option_verbose > 1) { XPR(NT "output file: %s\n", ofile->filename); } | 2770 | if (option_verbose > 1) { XPR(NT "output %s\n", ofile->filename); } |
2803 | } | 2771 | } |
2804 | 2772 | ||
2805 | #if EXTERNAL_COMPRESSION | 2773 | #if EXTERNAL_COMPRESSION |
@@ -2833,153 +2801,207 @@ main_set_source (xd3_stream *stream, xd3_cmd cmd, | |||
2833 | { | 2801 | { |
2834 | int ret = 0; | 2802 | int ret = 0; |
2835 | usize_t i; | 2803 | usize_t i; |
2836 | uint8_t *tmp_buf = NULL; | 2804 | usize_t blksize; |
2837 | xoff_t source_size = 0; | 2805 | xoff_t source_size = 0; |
2838 | int source_size_known = 0; | 2806 | main_blklru block0; |
2807 | |||
2808 | XD3_ASSERT (lru == NULL); | ||
2809 | XD3_ASSERT (stream->src == NULL); | ||
2810 | XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ); | ||
2839 | 2811 | ||
2840 | main_blklru_list_init (& lru_list); | 2812 | main_blklru_list_init (& lru_list); |
2841 | main_blklru_list_init (& lru_free); | 2813 | main_blklru_list_init (& lru_free); |
2842 | 2814 | ||
2843 | /* Open it, check for seekability, set required xd3_source fields. */ | ||
2844 | if (allow_fake_source) | 2815 | if (allow_fake_source) |
2845 | { | 2816 | { |
2846 | sfile->mode = XO_READ; | 2817 | sfile->mode = XO_READ; |
2847 | sfile->realname = sfile->filename; | 2818 | sfile->realname = sfile->filename; |
2848 | sfile->nread = 0; | 2819 | sfile->nread = 0; |
2849 | source_size_known = 1; | ||
2850 | } | 2820 | } |
2851 | else | 2821 | else |
2852 | { | 2822 | { |
2853 | int stat_val; | ||
2854 | |||
2855 | if ((ret = main_file_open (sfile, sfile->filename, XO_READ))) | 2823 | if ((ret = main_file_open (sfile, sfile->filename, XO_READ))) |
2856 | { | 2824 | { |
2857 | goto error; | 2825 | return ret; |
2858 | } | 2826 | } |
2859 | 2827 | ||
2860 | stat_val = main_file_stat (sfile, &source_size); | 2828 | sfile->size_known = (main_file_stat (sfile, &source_size) == 0); |
2861 | if (stat_val == 0) | ||
2862 | { | ||
2863 | source_size_known = 1; | ||
2864 | } | ||
2865 | else | ||
2866 | { | ||
2867 | source_size_known = 0; | ||
2868 | } | ||
2869 | } | 2829 | } |
2870 | 2830 | ||
2871 | if (source_size_known && source_size < option_srcwinsz) | 2831 | if (sfile->size_known && source_size < option_srcwinsz) |
2872 | { | 2832 | { |
2873 | /* Reduce sizes to actual source size, read whole file. */ | 2833 | blksize = (source_size / MIN_LRU_SIZE); |
2874 | option_srcwinsz = source_size; | ||
2875 | source->blksize = source_size; | ||
2876 | } | 2834 | } |
2877 | else | 2835 | else |
2878 | { | 2836 | { |
2879 | option_srcwinsz = max(option_srcwinsz, XD3_MINSRCWINSZ); | 2837 | blksize = (option_srcwinsz / MAX_LRU_SIZE); |
2880 | source->blksize = (option_srcwinsz / LRU_SIZE); | ||
2881 | } | 2838 | } |
2882 | 2839 | ||
2883 | if (source_size_known) | 2840 | blksize = max (blksize, XD3_MINSRCWINSZ); |
2884 | { | 2841 | |
2885 | IF_DEBUG2 (DP(RINT "[main_set_source] %s size %"Q"u\n", | 2842 | /* The API requires power-of-two blocksize, */ |
2886 | sfile->filename, source_size)); | 2843 | blksize = xd3_pow2_roundup (blksize); |
2887 | } | 2844 | |
2888 | else | 2845 | memset (&block0, 0, sizeof (block0)); |
2846 | block0.blkno = (xoff_t) -1; | ||
2847 | |||
2848 | /* Allocate the first block. Even if the size is known at this | ||
2849 | * point, we do not lower it because decompression may happen. */ | ||
2850 | if ((block0.blk = (uint8_t*) main_malloc (blksize)) == NULL) | ||
2889 | { | 2851 | { |
2890 | IF_DEBUG2 (DP(RINT "[main_set_source] %s size not known\n", | 2852 | ret = ENOMEM; |
2891 | sfile->filename, source_size)); | 2853 | return ret; |
2892 | main_internal_do_not_lru (); | ||
2893 | } | 2854 | } |
2894 | 2855 | ||
2856 | source->blksize = blksize; | ||
2895 | source->name = sfile->filename; | 2857 | source->name = sfile->filename; |
2896 | source->ioh = sfile; | 2858 | source->ioh = sfile; |
2897 | source->curblkno = 0; | 2859 | source->curblkno = (xoff_t) -1; |
2898 | source->curblk = NULL; | 2860 | source->curblk = NULL; |
2899 | 2861 | ||
2900 | /* DO NOT call xd3_set_source_and_size because of potential | 2862 | /* We have to read the first block into the cache now, because |
2901 | * secondary compression. */ | 2863 | * size_known can still change (due to secondary |
2902 | ret = xd3_set_source (stream, source); | 2864 | * decompression). Calls main_decompress_input_check() via |
2903 | if (ret) | 2865 | * main_read_primary_input(). */ |
2866 | lru_size = 1; | ||
2867 | lru = &block0; | ||
2868 | main_blklru_list_push_back (& lru_free, & lru[0]); | ||
2869 | ret = main_getblk_func (stream, source, 0); | ||
2870 | main_blklru_list_remove (& lru[0]); | ||
2871 | lru = NULL; | ||
2872 | |||
2873 | if (ret != 0) | ||
2904 | { | 2874 | { |
2905 | XPR(NT XD3_LIB_ERRMSG (stream, ret)); | 2875 | main_free (block0.blk); |
2906 | goto error; | 2876 | |
2877 | XPR(NT "error reading source %s: %s\n", | ||
2878 | sfile->filename, | ||
2879 | xd3_mainerror (ret)); | ||
2880 | |||
2881 | return ret; | ||
2907 | } | 2882 | } |
2908 | XD3_ASSERT (stream->src == source); | ||
2909 | 2883 | ||
2910 | lru_size = (option_srcwinsz + source->blksize - 1) / source->blksize; | 2884 | source->onblk = block0.size; |
2911 | lru_size = max(lru_size, 1U); | ||
2912 | IF_DEBUG1 (DP(RINT "[lru_size] == %d\n", lru_size)); | ||
2913 | option_srcwinsz = lru_size * source->blksize; | ||
2914 | 2885 | ||
2915 | if (option_verbose) | 2886 | /* If the file is smaller than a block, size is known. */ |
2887 | if (!sfile->size_known && source->onblk < blksize) | ||
2916 | { | 2888 | { |
2917 | static char winszbuf[32]; | 2889 | source_size = source->onblk; |
2918 | static char srcszbuf[32]; | 2890 | sfile->size_known = 1; |
2919 | static char blkszbuf[32]; | 2891 | } |
2920 | if (source_size_known) | ||
2921 | { | ||
2922 | sprintf(srcszbuf, " size %"Q"u", source_size); | ||
2923 | } | ||
2924 | else | ||
2925 | { | ||
2926 | strcpy(srcszbuf, " size not known"); | ||
2927 | } | ||
2928 | 2892 | ||
2929 | XPR(NT "source %s winsize %s blksize %s%s\n", | 2893 | /* source->size_known is finally determined. we update lru_size |
2930 | sfile->filename, | 2894 | * accordingly, and modify option_srcwinsz, which will be passed via |
2931 | main_format_bcnt(option_srcwinsz, winszbuf), | 2895 | * xd3_config. */ |
2932 | main_format_bcnt(source->blksize, blkszbuf), | 2896 | if (sfile->size_known && source_size <= option_srcwinsz) |
2933 | srcszbuf); | 2897 | { |
2898 | lru_size = (source_size + blksize - 1) / blksize; | ||
2899 | option_srcwinsz = lru_size * blksize; | ||
2900 | } | ||
2901 | else | ||
2902 | { | ||
2903 | lru_size = (option_srcwinsz + blksize - 1) / blksize; | ||
2904 | option_srcwinsz = lru_size * blksize; | ||
2934 | } | 2905 | } |
2935 | 2906 | ||
2936 | XD3_ASSERT (lru == NULL); | 2907 | XD3_ASSERT (lru_size >= 1); |
2937 | 2908 | ||
2938 | if ((lru = (main_blklru*) | 2909 | if ((lru = (main_blklru*) main_malloc (lru_size * sizeof (main_blklru))) == NULL) |
2939 | main_malloc (sizeof (main_blklru) * lru_size)) == NULL) | ||
2940 | { | 2910 | { |
2941 | ret = ENOMEM; | 2911 | ret = ENOMEM; |
2942 | goto error; | 2912 | return ret; |
2943 | } | 2913 | } |
2944 | 2914 | ||
2945 | for (i = 0; i < lru_size; i += 1) | 2915 | lru[0].blk = block0.blk; |
2916 | lru[0].blkno = 0; | ||
2917 | lru[0].size = source->onblk; | ||
2918 | |||
2919 | if (! sfile->size_known) | ||
2920 | { | ||
2921 | do_not_lru = 1; | ||
2922 | } | ||
2923 | else if (! do_not_lru) | ||
2924 | { | ||
2925 | main_blklru_list_push_back (& lru_list, & lru[0]); | ||
2926 | } | ||
2927 | |||
2928 | for (i = 1; i < lru_size; i += 1) | ||
2946 | { | 2929 | { |
2947 | lru[i].blkno = (xoff_t) -1; | 2930 | lru[i].blkno = (xoff_t) -1; |
2948 | 2931 | ||
2949 | if ((lru[i].blk = (uint8_t*) main_malloc (source->blksize)) == NULL) | 2932 | if ((lru[i].blk = (uint8_t*) main_malloc (source->blksize)) == NULL) |
2950 | { | 2933 | { |
2951 | ret = ENOMEM; | 2934 | ret = ENOMEM; |
2952 | goto error; | 2935 | return ret; |
2953 | } | 2936 | } |
2954 | 2937 | ||
2955 | if (! do_not_lru) | 2938 | if (do_not_lru == 0) |
2956 | { | 2939 | { |
2957 | main_blklru_list_push_back (& lru_free, & lru[i]); | 2940 | main_blklru_list_push_back (& lru_free, & lru[i]); |
2958 | } | 2941 | } |
2959 | } | 2942 | } |
2960 | 2943 | ||
2961 | if ((ret = main_getblk_func (stream, source, 0))) | 2944 | if (sfile->size_known) |
2945 | { | ||
2946 | ret = xd3_set_source_and_size (stream, source, source_size); | ||
2947 | } | ||
2948 | else | ||
2949 | { | ||
2950 | ret = xd3_set_source (stream, source); | ||
2951 | } | ||
2952 | |||
2953 | if (ret) | ||
2962 | { | 2954 | { |
2963 | XPR(NT "error reading first block: %s\n", xd3_mainerror (ret)); | 2955 | XPR(NT XD3_LIB_ERRMSG (stream, ret)); |
2964 | return ret; | 2956 | return ret; |
2965 | } | 2957 | } |
2966 | 2958 | ||
2967 | return 0; | 2959 | XD3_ASSERT (stream->src == source); |
2960 | XD3_ASSERT (source->blksize == blksize); | ||
2968 | 2961 | ||
2969 | error: | 2962 | if (option_verbose) |
2970 | IF_DEBUG2 (DP(RINT "[main_set_source] error %s\n", xd3_strerror (ret))); | ||
2971 | if (tmp_buf != NULL) | ||
2972 | { | 2963 | { |
2973 | main_free (tmp_buf); | 2964 | static char srcszbuf[32]; |
2965 | static char srccntbuf[32]; | ||
2966 | static char winszbuf[32]; | ||
2967 | static char blkszbuf[32]; | ||
2968 | static char nbufs[32]; | ||
2969 | |||
2970 | if (sfile->size_known) | ||
2971 | { | ||
2972 | sprintf (srcszbuf, "source size %s [%"Q"u]", | ||
2973 | main_format_bcnt (source_size, srccntbuf), | ||
2974 | source_size); | ||
2975 | } | ||
2976 | else | ||
2977 | { | ||
2978 | strcpy(srcszbuf, "source size unknown"); | ||
2979 | } | ||
2980 | |||
2981 | nbufs[0] = 0; | ||
2982 | |||
2983 | if (option_verbose > 1) | ||
2984 | { | ||
2985 | sprintf(nbufs, " #bufs %u", lru_size); | ||
2986 | } | ||
2987 | |||
2988 | XPR(NT "source %s %s blksize %s window %s%s%s\n", | ||
2989 | sfile->filename, | ||
2990 | srcszbuf, | ||
2991 | main_format_bcnt (blksize, blkszbuf), | ||
2992 | main_format_bcnt (option_srcwinsz, winszbuf), | ||
2993 | nbufs, | ||
2994 | do_not_lru ? " (FIFO)" : ""); | ||
2974 | } | 2995 | } |
2975 | 2996 | ||
2976 | return ret; | 2997 | return 0; |
2977 | } | 2998 | } |
2978 | 2999 | ||
2979 | static usize_t | 3000 | static usize_t |
2980 | main_get_winsize (main_file *ifile) { | 3001 | main_get_winsize (main_file *ifile) { |
2981 | xoff_t file_size = 0; | 3002 | xoff_t file_size = 0; |
2982 | usize_t size = option_winsize; | 3003 | usize_t size = option_winsize; |
3004 | static char iszbuf[32]; | ||
2983 | 3005 | ||
2984 | if (main_file_stat (ifile, &file_size) == 0) | 3006 | if (main_file_stat (ifile, &file_size) == 0) |
2985 | { | 3007 | { |
@@ -2990,7 +3012,9 @@ main_get_winsize (main_file *ifile) { | |||
2990 | 3012 | ||
2991 | if (option_verbose > 1) | 3013 | if (option_verbose > 1) |
2992 | { | 3014 | { |
2993 | XPR(NT "input window size: %u\n", size); | 3015 | XPR(NT "input %s window size %s\n", |
3016 | ifile->filename, | ||
3017 | main_format_bcnt (size, iszbuf)); | ||
2994 | } | 3018 | } |
2995 | 3019 | ||
2996 | return size; | 3020 | return size; |
@@ -3368,7 +3392,7 @@ main_input (xd3_cmd cmd, | |||
3368 | } | 3392 | } |
3369 | else | 3393 | else |
3370 | { | 3394 | { |
3371 | if (option_verbose > 1) | 3395 | if (option_verbose > 2) |
3372 | { | 3396 | { |
3373 | XPR(NT "compression level: %d\n", option_level); | 3397 | XPR(NT "compression level: %d\n", option_level); |
3374 | } | 3398 | } |
@@ -3590,13 +3614,15 @@ main_input (xd3_cmd cmd, | |||
3590 | XD3_ASSERT (stream.src != NULL); | 3614 | XD3_ASSERT (stream.src != NULL); |
3591 | } | 3615 | } |
3592 | 3616 | ||
3593 | /* Limited i-buffer size affects source copies */ | 3617 | /* Limited i-buffer size affects source copies |
3594 | if (option_verbose > 1 && | 3618 | * when the sourcewin is decided early. */ |
3619 | if (option_verbose && | ||
3620 | stream.srcwin_decided_early && | ||
3595 | stream.i_slots_used > stream.iopt_size) | 3621 | stream.i_slots_used > stream.iopt_size) |
3596 | { | 3622 | { |
3597 | XPR(NT "warning: input position %"Q"u overflowed " | 3623 | XPR(NT "warning: input position %"Q"u overflowed " |
3598 | "instruction buffer, needed %u (vs. %u), " | 3624 | "instruction buffer, needed %u (vs. %u), " |
3599 | "consider raising -I\n", | 3625 | "consider changing -I\n", |
3600 | stream.current_window * winsize, | 3626 | stream.current_window * winsize, |
3601 | stream.i_slots_used, stream.iopt_size); | 3627 | stream.i_slots_used, stream.iopt_size); |
3602 | } | 3628 | } |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 100f058..2231fe1 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -2486,7 +2486,6 @@ inline | |||
2486 | xoff_t xd3_source_eof(const xd3_source *src) | 2486 | xoff_t xd3_source_eof(const xd3_source *src) |
2487 | { | 2487 | { |
2488 | xoff_t r = (src->blksize * src->max_blkno) + (xoff_t)src->onlastblk; | 2488 | xoff_t r = (src->blksize * src->max_blkno) + (xoff_t)src->onlastblk; |
2489 | IF_DEBUG2 (DP(RINT "[src] source_size == %"Q"u\n", r)); | ||
2490 | return r; | 2489 | return r; |
2491 | } | 2490 | } |
2492 | 2491 | ||
@@ -2496,7 +2495,6 @@ usize_t xd3_bytes_on_srcblk (xd3_source *src, xoff_t blkno) | |||
2496 | usize_t r = (blkno == src->max_blkno ? | 2495 | usize_t r = (blkno == src->max_blkno ? |
2497 | src->onlastblk : | 2496 | src->onlastblk : |
2498 | src->blksize); | 2497 | src->blksize); |
2499 | IF_DEBUG2 (DP(RINT "[src] source last block size %u\n", r)); | ||
2500 | return r; | 2498 | return r; |
2501 | } | 2499 | } |
2502 | 2500 | ||
@@ -2773,6 +2771,11 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2773 | { | 2771 | { |
2774 | if ((ret = xd3_srcwin_setup (stream))) { return ret; } | 2772 | if ((ret = xd3_srcwin_setup (stream))) { return ret; } |
2775 | } | 2773 | } |
2774 | else | ||
2775 | { | ||
2776 | stream->srcwin_decided_early = (!stream->src->eof_known || | ||
2777 | (stream->srcwin_cksum_pos < xd3_source_eof (stream->src))); | ||
2778 | } | ||
2776 | 2779 | ||
2777 | /* xtra field indicates the copy is from the source */ | 2780 | /* xtra field indicates the copy is from the source */ |
2778 | if (inst->xtra) | 2781 | if (inst->xtra) |
@@ -3688,6 +3691,7 @@ xd3_encode_reset (xd3_stream *stream) | |||
3688 | stream->src->srcbase = 0; | 3691 | stream->src->srcbase = 0; |
3689 | stream->src->srclen = 0; | 3692 | stream->src->srclen = 0; |
3690 | stream->srcwin_decided = 0; | 3693 | stream->srcwin_decided = 0; |
3694 | stream->srcwin_decided_early = 0; | ||
3691 | stream->match_minaddr = 0; | 3695 | stream->match_minaddr = 0; |
3692 | stream->match_maxaddr = 0; | 3696 | stream->match_maxaddr = 0; |
3693 | stream->taroff = 0; | 3697 | stream->taroff = 0; |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 6258957..5b99a72 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -834,9 +834,12 @@ struct _xd3_stream | |||
834 | 834 | ||
835 | // SRCWIN | 835 | // SRCWIN |
836 | // these variables plus srcwin_maxsz above (set by config) | 836 | // these variables plus srcwin_maxsz above (set by config) |
837 | int srcwin_decided; /* boolean: true if the | 837 | int srcwin_decided; /* boolean: true if srclen and |
838 | srclen,srcbase have been | 838 | srcbase have been |
839 | decided. */ | 839 | decided. */ |
840 | int srcwin_decided_early; /* boolean: true if srclen | ||
841 | and srcbase were | ||
842 | decided early. */ | ||
840 | xoff_t srcwin_cksum_pos; /* Source checksum position */ | 843 | xoff_t srcwin_cksum_pos; /* Source checksum position */ |
841 | 844 | ||
842 | // MATCH | 845 | // MATCH |