summaryrefslogtreecommitdiff
path: root/xdelta3
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3')
-rwxr-xr-xxdelta3/xdelta3-main.h218
-rwxr-xr-xxdelta3/xdelta3-regtest.py2
2 files changed, 114 insertions, 106 deletions
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h
index 3dc5a5d..06190d0 100755
--- a/xdelta3/xdelta3-main.h
+++ b/xdelta3/xdelta3-main.h
@@ -256,6 +256,7 @@ static const char *option_source_filename = NULL;
256 256
257static usize_t option_winsize = XD3_DEFAULT_WINSIZE; 257static usize_t option_winsize = XD3_DEFAULT_WINSIZE;
258static usize_t option_srcwinsz = XD3_DEFAULT_SRCWINSZ; 258static usize_t option_srcwinsz = XD3_DEFAULT_SRCWINSZ;
259static int option_srcwinsz_set = 0;
259 260
260/* This controls the number of times main repeats itself, only for profiling. */ 261/* This controls the number of times main repeats itself, only for profiling. */
261static int option_profile_cnt = 0; 262static int option_profile_cnt = 0;
@@ -268,7 +269,7 @@ static int option_recompress_outputs = 1;
268#endif 269#endif
269 270
270/* This is for comparing "printdelta" output without attention to 271/* This is for comparing "printdelta" output without attention to
271 * copy-instruction modes, useful for reverse engineering. */ 272 * copy-instruction modes. */
272#if VCDIFF_TOOLS 273#if VCDIFF_TOOLS
273static int option_print_cpymode = 1; 274static int option_print_cpymode = 1;
274#endif 275#endif
@@ -1879,11 +1880,13 @@ main_open_output (xd3_stream *stream, main_file *ofile)
1879} 1880}
1880 1881
1881/* This is called at different times for encoding and decoding. The encoder calls it 1882/* This is called at different times for encoding and decoding. The encoder calls it
1882 * immediately, the decoder delays until the application header is received. */ 1883 * immediately, the decoder delays until the application header is received.
1884 * Stream may be NULL, in which case xd3_set_source is not called. */
1883static int 1885static int
1884main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *source) 1886main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *source)
1885{ 1887{
1886 int ret, i; 1888 int ret = 0, i;
1889 uint8_t *tmp_buf = NULL;
1887 1890
1888 /* Open it, check for seekability, set required xd3_source fields. */ 1891 /* Open it, check for seekability, set required xd3_source fields. */
1889 if (allow_fake_source) 1892 if (allow_fake_source)
@@ -1896,7 +1899,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
1896 else if ((ret = main_file_open (sfile, sfile->filename, XO_READ)) || 1899 else if ((ret = main_file_open (sfile, sfile->filename, XO_READ)) ||
1897 (ret = main_file_stat (sfile, & source->size, 1))) 1900 (ret = main_file_stat (sfile, & source->size, 1)))
1898 { 1901 {
1899 return ret; 1902 goto error;
1900 } 1903 }
1901 1904
1902 source->name = sfile->filename; 1905 source->name = sfile->filename;
@@ -1904,50 +1907,19 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
1904 source->curblkno = (xoff_t) -1; 1907 source->curblkno = (xoff_t) -1;
1905 source->curblk = NULL; 1908 source->curblk = NULL;
1906 1909
1907 /* Source block LRU init. */
1908 main_blklru_list_init (& lru_list);
1909 main_blklru_list_init (& lru_free);
1910
1911 // Note: to avoid unnecessary allocs for small files: problem
1912 // was with --decompress_inputs, we don't know the true size
1913 // option_srcwinsz = min(source->size, (xoff_t) option_srcwinsz);
1914
1915 if (option_verbose > 1) { XPR(NT "source window size: %u\n", option_srcwinsz); }
1916 if (option_verbose > 1) { XPR(NT "source block size: %u\n", source->blksize); }
1917
1918 lru_size = (option_srcwinsz / source->blksize);
1919 lru_size = max(1, lru_size);
1920
1921 if ((lru = main_malloc (sizeof (main_blklru) * lru_size)) == NULL)
1922 {
1923 return ENOMEM;
1924 }
1925
1926 for (i = 0; i < lru_size; i += 1)
1927 {
1928 lru[i].blkno = (xoff_t) -1;
1929
1930 if ((lru[i].blk = main_malloc (source->blksize)) == NULL)
1931 {
1932 return ENOMEM;
1933 }
1934
1935 main_blklru_list_push_back (& lru_free, & lru[i]);
1936 }
1937
1938#if EXTERNAL_COMPRESSION 1910#if EXTERNAL_COMPRESSION
1939 if (option_decompress_inputs) 1911 if (option_decompress_inputs)
1940 { 1912 {
1913 /* If encoding, read the header to check for decompression. */
1941 if (IS_ENCODE (cmd)) 1914 if (IS_ENCODE (cmd))
1942 { 1915 {
1943 usize_t nread; 1916 usize_t nread;
1917 tmp_buf = main_malloc(XD3_ALLOCSIZE);
1944 1918
1945 source->curblk = lru[0].blk; 1919 if ((ret = main_file_read (sfile, tmp_buf, XD3_ALLOCSIZE,
1946 1920 & nread, "source read failed")))
1947 /* If encoding, read the first block now to check for decompression. */
1948 if ((ret = main_file_read (sfile, (uint8_t*) source->curblk, source->blksize, & nread, "source read failed")))
1949 { 1921 {
1950 return ret; 1922 goto error;
1951 } 1923 }
1952 1924
1953 /* Check known magic numbers. */ 1925 /* Check known magic numbers. */
@@ -1955,23 +1927,16 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
1955 { 1927 {
1956 const main_extcomp *decomp = & extcomp_types[i]; 1928 const main_extcomp *decomp = & extcomp_types[i];
1957 1929
1958 if ((nread > decomp->magic_size) && memcmp (source->curblk, decomp->magic, decomp->magic_size) == 0) 1930 if ((nread > decomp->magic_size) &&
1931 memcmp (tmp_buf, decomp->magic, decomp->magic_size) == 0)
1959 { 1932 {
1960 sfile->compressor = decomp; 1933 sfile->compressor = decomp;
1961 break; 1934 break;
1962 } 1935 }
1963 } 1936 }
1964 1937
1965 /* If no decompression, the current buffer is now a valid source->curblock. */
1966 if (sfile->compressor == NULL) 1938 if (sfile->compressor == NULL)
1967 { 1939 {
1968 main_blklru_list_remove (& lru[0]);
1969 main_blklru_list_push_back (& lru_list, & lru[0]);
1970
1971 lru[0].blkno = 0;
1972 source->curblkno = 0;
1973 source->onblk = nread;
1974
1975 if (option_verbose > 2) 1940 if (option_verbose > 2)
1976 { 1941 {
1977 XPR(NT "source block 0 read (not compressed)\n"); 1942 XPR(NT "source block 0 read (not compressed)\n");
@@ -1988,12 +1953,13 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
1988 { 1953 {
1989 XPR(NT "source file too large for external decompression: %s: %"Q"u\n", 1954 XPR(NT "source file too large for external decompression: %s: %"Q"u\n",
1990 sfile->filename, osize); 1955 sfile->filename, osize);
1991 return XD3_INTERNAL; 1956 ret = XD3_INTERNAL;
1957 goto error;
1992 } 1958 }
1993 1959
1994 if ((ret = main_decompress_source (sfile, source))) 1960 if ((ret = main_decompress_source (sfile, source)))
1995 { 1961 {
1996 return ret; 1962 goto error;
1997 } 1963 }
1998 1964
1999 if (! option_quiet) 1965 if (! option_quiet)
@@ -2012,15 +1978,72 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
2012 } 1978 }
2013#endif 1979#endif
2014 1980
2015 if (option_verbose > 1) { XPR(NT "source file: %s: %"Q"u bytes\n", sfile->realname, source->size); } 1981 /* At this point we know source->size.
1982 * Source buffer, blksize, LRU init. */
1983 if (source->size < option_srcwinsz)
1984 {
1985 /* Reduce sizes to actual source size, read whole file */
1986 option_srcwinsz = source->size;
1987 source->blksize = source->size;
1988 lru_size = 1;
1989 }
1990 else
1991 {
1992 /* Minimum size check */
1993 option_srcwinsz = max(option_srcwinsz, XD3_ALLOCSIZE);
1994
1995 if (!option_srcwinsz_set)
1996 {
1997 /* If the flag was not set, scale srcwinsz up to 64MB. */
1998 option_srcwinsz = min(1ULL<<26, source->size);
1999 }
2000
2001 source->blksize = (option_srcwinsz / 32) & ~(XD3_ALLOCSIZE - 1);;
2002 lru_size = 32;
2003 }
2004
2005 main_blklru_list_init (& lru_list);
2006 main_blklru_list_init (& lru_free);
2007
2008 if ((lru = main_malloc (sizeof (main_blklru) * lru_size)) == NULL)
2009 {
2010 ret = ENOMEM;
2011 goto error;
2012 }
2013
2014 for (i = 0; i < lru_size; i += 1)
2015 {
2016 lru[i].blkno = (xoff_t) -1;
2017
2018 if ((lru[i].blk = main_malloc (source->blksize)) == NULL)
2019 {
2020 ret = ENOMEM;
2021 goto error;
2022 }
2023
2024 main_blklru_list_push_back (& lru_free, & lru[i]);
2025 }
2026
2027 if (option_verbose > 1)
2028 {
2029 XPR(NT "source window size: %u\n", option_srcwinsz);
2030 XPR(NT "source block size: %u\n", source->blksize);
2031 XPR(NT "source file: %s: %"Q"u bytes\n", sfile->realname, source->size);
2032 }
2016 2033
2017 if ((ret = xd3_set_source (stream, source))) 2034 if (stream && (ret = xd3_set_source (stream, source)))
2018 { 2035 {
2019 XPR(NT XD3_LIB_ERRMSG (stream, ret)); 2036 XPR(NT XD3_LIB_ERRMSG (stream, ret));
2020 return EXIT_FAILURE; 2037 goto error;
2021 } 2038 }
2022 2039
2023 return 0; 2040 error:
2041 if (tmp_buf != NULL)
2042 {
2043 main_free (tmp_buf);
2044 }
2045
2046 return ret;
2024} 2047}
2025 2048
2026/****************************************************************************************** 2049/******************************************************************************************
@@ -2174,7 +2197,6 @@ main_input (xd3_cmd cmd,
2174 xoff_t last_total_in = 0; 2197 xoff_t last_total_in = 0;
2175 xoff_t last_total_out = 0; 2198 xoff_t last_total_out = 0;
2176 long start_time; 2199 long start_time;
2177 xoff_t input_size = 0;
2178 int stdout_only = 0; 2200 int stdout_only = 0;
2179 2201
2180 int (*input_func) (xd3_stream*); 2202 int (*input_func) (xd3_stream*);
@@ -2189,6 +2211,9 @@ main_input (xd3_cmd cmd,
2189 config.sec_addr.ngroups = 1; 2211 config.sec_addr.ngroups = 1;
2190 config.sec_inst.ngroups = 1; 2212 config.sec_inst.ngroups = 1;
2191 2213
2214 /* TODO: eliminate static variables. */
2215 do_not_lru = 0;
2216
2192 /* main_input setup. */ 2217 /* main_input setup. */
2193 switch ((int) cmd) 2218 switch ((int) cmd)
2194 { 2219 {
@@ -2205,6 +2230,7 @@ main_input (xd3_cmd cmd,
2205#endif 2230#endif
2206#if XD3_ENCODER 2231#if XD3_ENCODER
2207 case CMD_ENCODE: 2232 case CMD_ENCODE:
2233 do_not_lru = 1;
2208 input_func = xd3_encode_input; 2234 input_func = xd3_encode_input;
2209 output_func = main_write_output; 2235 output_func = main_write_output;
2210 2236
@@ -2286,24 +2312,6 @@ main_input (xd3_cmd cmd,
2286 2312
2287 start_time = get_millisecs_now (); 2313 start_time = get_millisecs_now ();
2288 2314
2289 if (main_file_stat (ifile, & input_size, 0) == 0)
2290 {
2291 // Note: to avoid unnecessary allocs for small files: problem
2292 // was with --decompress_inputs, we don't know the true size
2293 // option_winsize = min (input_size, (xoff_t) option_winsize);
2294 }
2295
2296 option_srcwinsz = max(option_srcwinsz, XD3_ALLOCSIZE);
2297 option_winsize = max(option_winsize, XD3_ALLOCSIZE);
2298
2299 source.blksize = (option_srcwinsz / 32) & ~(XD3_ALLOCSIZE-1);
2300 source.blksize = max(XD3_DEFAULT_WINSIZE, source.blksize);
2301
2302 config.srcwin_maxsz = option_srcwinsz;
2303 config.winsize = option_winsize;
2304 config.getblk = main_getblk_func;
2305 config.flags = stream_flags;
2306
2307 if (option_verbose > 1) 2315 if (option_verbose > 1)
2308 { 2316 {
2309 XPR(NT "input buffer size: %u\n", option_winsize); 2317 XPR(NT "input buffer size: %u\n", option_winsize);
@@ -2314,22 +2322,36 @@ main_input (xd3_cmd cmd,
2314 return EXIT_FAILURE; 2322 return EXIT_FAILURE;
2315 } 2323 }
2316 2324
2317 if ((ret = xd3_config_stream (& stream, & config)))
2318 {
2319 XPR(NT XD3_LIB_ERRMSG (& stream, ret));
2320 return EXIT_FAILURE;
2321 }
2322
2323 if (IS_ENCODE (cmd)) 2325 if (IS_ENCODE (cmd))
2324 { 2326 {
2325 /* When encoding, open the source file, possibly decompress it. The decoder delays 2327 /* When encoding, open the source file, possibly decompress it. The decoder delays
2326 * this step until XD3_GOTHEADER. */ 2328 * this step until XD3_GOTHEADER. */
2327 if (sfile->filename != NULL && (ret = main_set_source (& stream, cmd, sfile, & source))) 2329 if (sfile->filename != NULL && (ret = main_set_source (NULL, cmd, sfile, & source)))
2328 { 2330 {
2329 return EXIT_FAILURE; 2331 return EXIT_FAILURE;
2330 } 2332 }
2331 } 2333 }
2332 2334
2335 option_winsize = max(option_winsize, XD3_ALLOCSIZE);
2336
2337 config.winsize = option_winsize;
2338 config.srcwin_maxsz = option_srcwinsz;
2339 config.getblk = main_getblk_func;
2340 config.flags = stream_flags;
2341
2342 if ((ret = xd3_config_stream (& stream, & config)))
2343 {
2344 XPR(NT XD3_LIB_ERRMSG (& stream, ret));
2345 return EXIT_FAILURE;
2346 }
2347
2348 if (IS_ENCODE (cmd) && sfile->filename != NULL &&
2349 (ret = xd3_set_source (& stream, & source)))
2350 {
2351 XPR(NT XD3_LIB_ERRMSG (& stream, ret));
2352 return EXIT_FAILURE;
2353 }
2354
2333 /* This times each window. */ 2355 /* This times each window. */
2334 get_millisecs_since (); 2356 get_millisecs_since ();
2335 2357
@@ -2341,9 +2363,8 @@ main_input (xd3_cmd cmd,
2341 usize_t try_read; 2363 usize_t try_read;
2342 2364
2343 input_offset = ifile->nread; 2365 input_offset = ifile->nread;
2344 /*XD3_ASSERT (input_offset <= option_last_offset);*/
2345 2366
2346 input_remain = /*option_last_offset*/ XOFF_T_MAX - input_offset; 2367 input_remain = XOFF_T_MAX - input_offset;
2347 2368
2348 try_read = (usize_t) min ((xoff_t) config.winsize, input_remain); 2369 try_read = (usize_t) min ((xoff_t) config.winsize, input_remain);
2349 2370
@@ -2376,7 +2397,6 @@ main_input (xd3_cmd cmd,
2376 2397
2377 again: 2398 again:
2378 ret = input_func (& stream); 2399 ret = input_func (& stream);
2379 /*if (option_verbose > 1) { XPR(NT XD3_LIB_ERRMSG (& stream, ret)); }*/
2380 2400
2381 switch (ret) 2401 switch (ret)
2382 { 2402 {
@@ -2436,22 +2456,14 @@ main_input (xd3_cmd cmd,
2436 /* FALLTHROUGH */ 2456 /* FALLTHROUGH */
2437 case XD3_WINSTART: 2457 case XD3_WINSTART:
2438 { 2458 {
2439 /* Set or unset XD3_SKIP_WINDOW. */ 2459 /* e.g., set or unset XD3_SKIP_WINDOW. */
2440 /*if (stream.current_window < option_first_window || 2460 /* xd3_set_flags (& stream, stream_flags); */
2441 stream.current_window > option_last_window)
2442 { stream_flags |= XD3_SKIP_WINDOW; }
2443 else
2444 { stream_flags &= ~XD3_SKIP_WINDOW; }*/
2445
2446 xd3_set_flags (& stream, stream_flags);
2447 goto again; 2461 goto again;
2448 } 2462 }
2449 2463
2450 case XD3_OUTPUT: 2464 case XD3_OUTPUT:
2451 { 2465 {
2452 if (option_no_output == 0/* && 2466 if (option_no_output == 0)
2453 stream.current_window >= option_first_window &&
2454 stream.current_window <= option_last_window*/)
2455 { 2467 {
2456 /* Defer opening the output file until the stream produces its first 2468 /* Defer opening the output file until the stream produces its first
2457 * output for both encoder and decoder, this way we delay long enough for 2469 * output for both encoder and decoder, this way we delay long enough for
@@ -2664,7 +2676,7 @@ main (int argc, char **argv)
2664 * main() and thus care about freeing all memory. I never had much trust for getopt 2676 * main() and thus care about freeing all memory. I never had much trust for getopt
2665 * anyway, it's too opaque. This implements a fairly standard non-long-option getopt 2677 * anyway, it's too opaque. This implements a fairly standard non-long-option getopt
2666 * with support for named operations (e.g., "xdelta3 [encode|decode|printhdr...] < in > 2678 * with support for named operations (e.g., "xdelta3 [encode|decode|printhdr...] < in >
2667 * out"). I'll probably add long options at some point. */ 2679 * out"). */
2668 if (my_optstr) 2680 if (my_optstr)
2669 { 2681 {
2670 if (*my_optstr == '-') { my_optstr += 1; } 2682 if (*my_optstr == '-') { my_optstr += 1; }
@@ -2824,10 +2836,12 @@ main (int argc, char **argv)
2824 else { option_use_secondary = 1; option_secondary = my_optarg; } break; 2836 else { option_use_secondary = 1; option_secondary = my_optarg; } break;
2825 case 'A': if (my_optarg == NULL) { option_use_appheader = 0; } 2837 case 'A': if (my_optarg == NULL) { option_use_appheader = 0; }
2826 else { option_appheader = (uint8_t*) my_optarg; } break; 2838 else { option_appheader = (uint8_t*) my_optarg; } break;
2827 case 'B': if ((ret = main_atou (my_optarg, & option_srcwinsz, XD3_ALLOCSIZE, 'B'))) 2839 case 'B':
2828 { 2840 option_srcwinsz_set = 1;
2829 goto exit; 2841 if ((ret = main_atou (my_optarg, & option_srcwinsz, XD3_ALLOCSIZE, 'B')))
2830 } 2842 {
2843 goto exit;
2844 }
2831 break; 2845 break;
2832 case 'W': if ((ret = main_atou (my_optarg, & option_winsize, XD3_ALLOCSIZE, 'W'))) 2846 case 'W': if ((ret = main_atou (my_optarg, & option_winsize, XD3_ALLOCSIZE, 'W')))
2833 { 2847 {
@@ -2947,10 +2961,6 @@ main (int argc, char **argv)
2947 case CMD_PRINTDELTA: 2961 case CMD_PRINTDELTA:
2948#if XD3_ENCODER 2962#if XD3_ENCODER
2949 case CMD_ENCODE: 2963 case CMD_ENCODE:
2950 if (cmd == CMD_ENCODE)
2951 {
2952 do_not_lru = 1;
2953 }
2954#endif 2964#endif
2955 case CMD_DECODE: 2965 case CMD_DECODE:
2956 ret = main_input (cmd, & ifile, & ofile, & sfile); 2966 ret = main_input (cmd, & ifile, & ofile, & sfile);
diff --git a/xdelta3/xdelta3-regtest.py b/xdelta3/xdelta3-regtest.py
index 578311c..536c086 100755
--- a/xdelta3/xdelta3-regtest.py
+++ b/xdelta3/xdelta3-regtest.py
@@ -500,8 +500,6 @@ def Test():
500 print StatList([x.totrev for x in rcsf.rcsfiles], "totrev", 1).str 500 print StatList([x.totrev for x in rcsf.rcsfiles], "totrev", 1).str
501 pairs = rcsf.PairsByDate(Xdelta3Pair()) 501 pairs = rcsf.PairsByDate(Xdelta3Pair())
502 502
503 print pairs
504
505def Decimals(max): 503def Decimals(max):
506 l = [0] 504 l = [0]
507 step = 1 505 step = 1