summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xdelta3/Makefile3
-rw-r--r--xdelta3/setup.py1
-rw-r--r--xdelta3/xdelta3-main.h8
-rwxr-xr-xxdelta3/xdelta3-regtest.py107
-rw-r--r--xdelta3/xdelta3.h9
5 files changed, 82 insertions, 46 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile
index 2d2b785..3bb7f44 100644
--- a/xdelta3/Makefile
+++ b/xdelta3/Makefile
@@ -48,6 +48,7 @@ EXTRA = Makefile COPYING linkxd3lib.c badcopy.c xdelta3.swig \
48 48
49SWIG_FLAGS = -DXD3_DEBUG=0 \ 49SWIG_FLAGS = -DXD3_DEBUG=0 \
50 -DXD3_USE_LARGEFILE64=1 \ 50 -DXD3_USE_LARGEFILE64=1 \
51 -DGENERIC_ENCODE_TABLES=1 \
51 -DSECONDARY_DJW=1 \ 52 -DSECONDARY_DJW=1 \
52 -DVCDIFF_TOOLS=1 \ 53 -DVCDIFF_TOOLS=1 \
53 -DSWIG_MODULE=1 \ 54 -DSWIG_MODULE=1 \
@@ -105,7 +106,7 @@ xdelta3-debug3: $(SOURCES)
105 $(CC) -g -Wall -Wshadow xdelta3.c -o xdelta3-debug3 -DXD3_MAIN=1 -DGENERIC_ENCODE_TABLES=1 \ 106 $(CC) -g -Wall -Wshadow xdelta3.c -o xdelta3-debug3 -DXD3_MAIN=1 -DGENERIC_ENCODE_TABLES=1 \
106 -DXD3_USE_LARGEFILE64=1 -DXD3_STDIO=1 -DREGRESSION_TEST=1 -DXD3_DEBUG=3 -DSECONDARY_DJW=1 -DSECONDARY_FGK=1 -lm 107 -DXD3_USE_LARGEFILE64=1 -DXD3_STDIO=1 -DREGRESSION_TEST=1 -DXD3_DEBUG=3 -DSECONDARY_DJW=1 -DSECONDARY_FGK=1 -lm
107 108
108$(PYTGT): $(SOURCES) 109$(PYTGT): $(SOURCES) setup.py
109 $(PYTHON) setup.py install --verbose --compile --force 110 $(PYTHON) setup.py install --verbose --compile --force
110 111
111xdelta3_wrap.c xdelta3.py: xdelta3.swig 112xdelta3_wrap.c xdelta3.py: xdelta3.swig
diff --git a/xdelta3/setup.py b/xdelta3/setup.py
index d7f11c4..f89aba7 100644
--- a/xdelta3/setup.py
+++ b/xdelta3/setup.py
@@ -37,6 +37,7 @@ xdelta3_ext = Extension('xdelta3main',
37 ('PYTHON_MODULE',1), 37 ('PYTHON_MODULE',1),
38 ('SECONDARY_DJW',1), 38 ('SECONDARY_DJW',1),
39 ('VCDIFF_TOOLS',1), 39 ('VCDIFF_TOOLS',1),
40 ('GENERIC_ENCODE_TABLES',1),
40 ('XD3_POSIX',1), 41 ('XD3_POSIX',1),
41 ('XD3_USE_LARGEFILE64',1), 42 ('XD3_USE_LARGEFILE64',1),
42 43
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h
index 44f51ee..2f1eb7f 100644
--- a/xdelta3/xdelta3-main.h
+++ b/xdelta3/xdelta3-main.h
@@ -400,7 +400,6 @@ reset_defaults(void)
400 option_srcwinsz_set = 0; 400 option_srcwinsz_set = 0;
401 option_smatch_config = NULL; 401 option_smatch_config = NULL;
402 option_level = XD3_DEFAULT_LEVEL; 402 option_level = XD3_DEFAULT_LEVEL;
403 option_winsize = XD3_DEFAULT_WINSIZE;
404 option_srcwinsz = XD3_DEFAULT_SRCWINSZ; 403 option_srcwinsz = XD3_DEFAULT_SRCWINSZ;
405 option_winsize = XD3_DEFAULT_WINSIZE; 404 option_winsize = XD3_DEFAULT_WINSIZE;
406 option_srcwinsz = XD3_DEFAULT_SRCWINSZ; 405 option_srcwinsz = XD3_DEFAULT_SRCWINSZ;
@@ -2668,15 +2667,16 @@ main_input (xd3_cmd cmd,
2668 /* Warn when no source copies are found */ 2667 /* Warn when no source copies are found */
2669 if (! xd3_encoder_used_source (& stream)) 2668 if (! xd3_encoder_used_source (& stream))
2670 { 2669 {
2671 XPR(NT "warning: input position %"Q"u no source copies\n", 2670 XPR(NT "warning: input window %"Q"u..%"Q"u has no source copies\n",
2672 stream.current_window * option_winsize); 2671 stream.current_window * option_winsize,
2672 (stream.current_window+1) * option_winsize);
2673 } 2673 }
2674 2674
2675 /* Limited instruction buffer size affects source copies */ 2675 /* Limited instruction buffer size affects source copies */
2676 if (option_verbose > 1 && stream.i_slots_used > stream.iopt_size) 2676 if (option_verbose > 1 && stream.i_slots_used > stream.iopt_size)
2677 { 2677 {
2678 XPR(NT "warning: input position %"Q"u overflowed instruction buffer, " 2678 XPR(NT "warning: input position %"Q"u overflowed instruction buffer, "
2679 "needed %u (vs. %u)\n", 2679 "needed %u (vs. %u), consider raising -I\n",
2680 stream.current_window * option_winsize, 2680 stream.current_window * option_winsize,
2681 stream.i_slots_used, stream.iopt_size); 2681 stream.i_slots_used, stream.iopt_size);
2682 } 2682 }
diff --git a/xdelta3/xdelta3-regtest.py b/xdelta3/xdelta3-regtest.py
index 1dc6c0a..30bccb1 100755
--- a/xdelta3/xdelta3-regtest.py
+++ b/xdelta3/xdelta3-regtest.py
@@ -16,7 +16,6 @@
16# along with this program; if not, write to the Free Software 16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18
19# TODO: Start testing window sizes
20# TODO: Test 1.5 vs. greedy 19# TODO: Test 1.5 vs. greedy
21# TODO: Compare w/ bsdiff and generate more summary 20# TODO: Compare w/ bsdiff and generate more summary
22 21
@@ -39,12 +38,15 @@ MIN_RUN = 1000 * 1000 * 1
39MAX_RUN = 1000 * 1000 * 10 38MAX_RUN = 1000 * 1000 * 10
40 39
41# How many results per round 40# How many results per round
42MAX_RESULTS = 10 41MAX_RESULTS = 6
43KEEP_P = (0.5) 42KEEP_P = (1.0)
44FAST_P = (0.0) 43FAST_P = (0.0)
45SLOW_P = (0.0) 44SLOW_P = (0.0)
46FILE_P = (0.30) 45FILE_P = (0.30)
47 46
47# the first 10 args go to -C
48SOFT_CONFIG_CNT = 10
49
48CONFIG_ORDER = [ 'large_look', 50CONFIG_ORDER = [ 'large_look',
49 'large_step', 51 'large_step',
50 'small_look', 52 'small_look',
@@ -54,23 +56,36 @@ CONFIG_ORDER = [ 'large_look',
54 'trylazy', 56 'trylazy',
55 'max_lazy', 57 'max_lazy',
56 'long_enough', 58 'long_enough',
57 'promote' ] 59 'promote',
60 'winsize',
61 'srcwinsize',
62 ]
63
64CONFIG_ARGMAP = {
65 'winsize' : '-W',
66 'srcwinsize' : '-B',
67 }
58 68
59def INPUT_SPEC(rand): 69def INPUT_SPEC(rand):
60 return { 70 return {
61 'large_look' : lambda d: rand.choice([9, 11, 13, 15]), 71 'large_look' : lambda d: rand.choice([9]),
62 'large_step' : lambda d: rand.choice([11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 ]), 72 'large_step' : lambda d: rand.choice([15]),
63 73
64 'small_chain' : lambda d: rand.choice([1]), 74 'small_chain' : lambda d: rand.choice([1]),
65 'small_lchain' : lambda d: rand.choice([1]), 75 'small_lchain' : lambda d: rand.choice([1]),
66 76
67 'max_lazy' : lambda d: rand.choice([9, 13, 18]), 77 'max_lazy' : lambda d: rand.choice([18]),
68 'long_enough' : lambda d: rand.choice([9, 13, 18]), 78 'long_enough' : lambda d: rand.choice([18]),
69 79
70 'small_look' : lambda d: rand.choice([4]), 80 'small_look' : lambda d: rand.choice([4]),
71 'promote' : lambda d: 0, 81 'promote' : lambda d: 0,
72 'trylazy' : lambda d: 1, 82 'trylazy' : lambda d: 1,
73 'ssmatch' : lambda d: 0, 83 'ssmatch' : lambda d: 0,
84
85 'winsize' : lambda d: rand.choice(
86 [x * (1<<20) for x in [1, 4, 8, 16, 32, 64]]),
87
88 'srcwinsize' : lambda d: 1<<26,
74 } 89 }
75 90
76 91
@@ -313,7 +328,7 @@ class Xdelta3RunClass:
313 #end 328 #end
314 329
315 def __str__(self): 330 def __str__(self):
316 return 'xdelta3' 331 return ' '.join(self.extra)
317 #end 332 #end
318 333
319 def New(self): 334 def New(self):
@@ -624,13 +639,15 @@ class RcsFile:
624 639
625 target_size = os.stat(self.Verf(v+1)).st_size 640 target_size = os.stat(self.Verf(v+1)).st_size
626 641
627 print '%s %s %s: %.2f%% encode %.3f ms: decode %.3f ms' % \ 642 if 0:
643 print '%s %s %s: %.2f%% encode %.3f ms: decode %.3f ms' % \
628 (runclass, 644 (runclass,
629 os.path.basename(self.fname), 645 os.path.basename(self.fname),
630 self.Vstr(v+1), 646 self.Vstr(v+1),
631 target_size > 0 and (100.0 * result.encode_size / target_size) or 0, 647 target_size > 0 and (100.0 * result.encode_size / target_size) or 0,
632 result.encode_time.mean * 1000.0, 648 result.encode_time.mean * 1000.0,
633 result.decode_time.mean * 1000.0) 649 result.decode_time.mean * 1000.0)
650 #end
634 ntrials.append(result) 651 ntrials.append(result)
635 #end 652 #end
636 653
@@ -716,9 +733,23 @@ class RcsFinder:
716 good.append(rf) 733 good.append(rf)
717 #end 734 #end
718 self.rcsfiles = good 735 self.rcsfiles = good
736 ReportPairs(runclass, results)
719 return results 737 return results
720 #end 738 #end
721 739
740def ReportPairs(name, results):
741 encode_time = 0
742 decode_time = 0
743 encode_size = 0
744 for r in results:
745 encode_time += r.encode_time.mean
746 decode_time += r.decode_time.mean
747 encode_size += r.encode_size
748 #end
749 print '%s rcs: encode %.2f s: decode %.2f s: size %d' % \
750 (name, encode_time, decode_time, encode_size)
751#end
752
722def GetTestRcsFiles(): 753def GetTestRcsFiles():
723 rcsf = RcsFinder() 754 rcsf = RcsFinder()
724 rcsf.Crawl(RCSDIR) 755 rcsf.Crawl(RCSDIR)
@@ -831,6 +862,17 @@ class RandomTester:
831 862
832 return config 863 return config
833 864
865 def ConfigToArgs(self, config):
866 args = [ '-C',
867 ','.join([str(x) for x in config[0:SOFT_CONFIG_CNT]])]
868 for i in range(SOFT_CONFIG_CNT, len(CONFIG_ORDER)):
869 key = CONFIG_ARGMAP[CONFIG_ORDER[i]]
870 val = config[i]
871 args.append('%s=%s' % (key, val))
872 #end
873 return args
874 #end
875
834 def MakeBigFiles(self, rcsf): 876 def MakeBigFiles(self, rcsf):
835 f1 = open(TMPDIR + "/big.1", "w") 877 f1 = open(TMPDIR + "/big.1", "w")
836 f2 = open(TMPDIR + "/big.2", "w") 878 f2 = open(TMPDIR + "/big.2", "w")
@@ -871,7 +913,7 @@ class RandomTester:
871 config = self.RandomConfig() 913 config = self.RandomConfig()
872 #end 914 #end
873 915
874 args = [ '-C', ','.join([str(x) for x in config]) ] 916 args = self.ConfigToArgs(config)
875 result = TimedTest(f2, f1, Xdelta3Runner(args)) 917 result = TimedTest(f2, f1, Xdelta3Runner(args))
876 918
877 tr = RandomTestResult(self.round_num, 919 tr = RandomTestResult(self.round_num,
@@ -935,6 +977,19 @@ class RandomTester:
935 best_by_time = [] 977 best_by_time = []
936 978
937 print 'Worst: %s' % scored[len(scored)-1][1] 979 print 'Worst: %s' % scored[len(scored)-1][1]
980
981 pos = 0
982 for (score, test) in scored:
983 pos += 1
984 test.score_pos = pos
985 c = c2s(test.config())
986 if not test_totals.has_key(c):
987 test_totals[c] = [test]
988 else:
989 test_totals[c].append(test)
990 #end
991 #end
992
938 scored = [x[1] for x in scored[0:int(MAX_RESULTS * KEEP_P)]] 993 scored = [x[1] for x in scored[0:int(MAX_RESULTS * KEEP_P)]]
939 994
940 for fast in [x[1] for x in timed[0:int(MAX_RESULTS * FAST_P)]]: 995 for fast in [x[1] for x in timed[0:int(MAX_RESULTS * FAST_P)]]:
@@ -959,16 +1014,8 @@ class RandomTester:
959 #end 1014 #end
960 1015
961 r = [] 1016 r = []
962 pos = 0
963 for test in scored: 1017 for test in scored:
964 pos += 1
965 test.score_pos = pos
966 c = c2s(test.config()) 1018 c = c2s(test.config())
967 if not test_totals.has_key(c):
968 test_totals[c] = [test]
969 else:
970 test_totals[c].append(test)
971 #end
972 s = 0.0 1019 s = 0.0
973 self.results.append(test) 1020 self.results.append(test)
974 r.append(test.config()) 1021 r.append(test.config())
@@ -1046,19 +1093,6 @@ def RunSampleDataTest():
1046 #end 1093 #end
1047#end 1094#end
1048 1095
1049def ReportPairs(name, results):
1050 encode_time = 0
1051 decode_time = 0
1052 encode_size = 0
1053 for r in results:
1054 encode_time += r.encode_time.mean
1055 decode_time += r.decode_time.mean
1056 encode_size += r.encode_size
1057 #end
1058 print '%s rcs: encode %.2f s: decode %.2f s: size %d' % \
1059 (name, encode_time, decode_time, encode_size)
1060#end
1061
1062if __name__ == "__main__": 1096if __name__ == "__main__":
1063 try: 1097 try:
1064 RunCommand(['rm', '-rf', TMPDIR]) 1098 RunCommand(['rm', '-rf', TMPDIR])
@@ -1066,10 +1100,11 @@ if __name__ == "__main__":
1066 1100
1067 #RunSpeedTest() 1101 #RunSpeedTest()
1068 1102
1069 rcsf = GetTestRcsFiles() 1103 #rcsf = GetTestRcsFiles()
1070 1104
1071 x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-S', 'djw'])) 1105 #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9']))
1072 ReportPairs('xd3 -9', x3r) 1106 #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-S', 'djw']))
1107 #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-T']))
1073 1108
1074 #x3r = rcsf.AllPairsByDate(Xdelta3RunClass([])) 1109 #x3r = rcsf.AllPairsByDate(Xdelta3RunClass([]))
1075 #ReportPairs('xdelta3', x3r) 1110 #ReportPairs('xdelta3', x3r)
@@ -1078,7 +1113,7 @@ if __name__ == "__main__":
1078 #ReportPairs('xdelta1', x1r) 1113 #ReportPairs('xdelta1', x1r)
1079 1114
1080 #RunRandomRcsTest(rcsf) 1115 #RunRandomRcsTest(rcsf)
1081 #RunSampleDataTest() 1116 RunSampleDataTest()
1082 1117
1083 except CommandError: 1118 except CommandError:
1084 pass 1119 pass
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h
index cee63cf..b4c0a4e 100644
--- a/xdelta3/xdelta3.h
+++ b/xdelta3/xdelta3.h
@@ -51,10 +51,9 @@
51 51
52/* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect decoders against 52/* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect decoders against
53 * malicious files. The decoder will never decode a window larger than this. If the file 53 * malicious files. The decoder will never decode a window larger than this. If the file
54 * specifies VCD_TARGET the decoder may require two buffers of this size. Rationale for 54 * specifies VCD_TARGET the decoder may require two buffers of this size.
55 * choosing 22-bits as a maximum: this means that in the worst case, any VCDIFF address 55 *
56 * without a copy window will require 3 bytes to encode (7 bits per byte, HERE and SAME 56 * 8-16MB is reasonable, probably don't need to go larger.
57 * modes making every address within half the window away. */
58#ifndef XD3_HARDMAXWINSIZE 57#ifndef XD3_HARDMAXWINSIZE
59#define XD3_HARDMAXWINSIZE (1U<<24) 58#define XD3_HARDMAXWINSIZE (1U<<24)
60#endif 59#endif
@@ -64,7 +63,7 @@
64 * seekable, they are decompressed to a temporary file location and the user may not wish 63 * seekable, they are decompressed to a temporary file location and the user may not wish
65 * for this. */ 64 * for this. */
66#ifndef XD3_NODECOMPRESSSIZE 65#ifndef XD3_NODECOMPRESSSIZE
67#define XD3_NODECOMPRESSSIZE (1U<<24) 66#define XD3_NODECOMPRESSSIZE (1U<<28)
68#endif 67#endif
69 68
70/* The IOPT_SIZE value sets the size of a buffer used to batch overlapping copy 69/* The IOPT_SIZE value sets the size of a buffer used to batch overlapping copy