diff options
-rw-r--r-- | xdelta3/xdelta3-main.h | 6 | ||||
-rwxr-xr-x | xdelta3/xdelta3-regtest.py | 81 | ||||
-rwxr-xr-x | xdelta3/xdelta3-test.py | 22 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 44 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 24 | ||||
-rw-r--r-- | xdelta3/xdelta3.swig | 28 |
6 files changed, 139 insertions, 66 deletions
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 50cbb67..44f51ee 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -2454,7 +2454,11 @@ main_input (xd3_cmd cmd, | |||
2454 | { | 2454 | { |
2455 | XPR(NT "compression level: %d\n", option_level); | 2455 | XPR(NT "compression level: %d\n", option_level); |
2456 | } | 2456 | } |
2457 | if (option_level == 0) { stream_flags |= XD3_NOCOMPRESS; } | 2457 | if (option_level == 0) |
2458 | { | ||
2459 | stream_flags |= XD3_NOCOMPRESS; | ||
2460 | config.smatch_cfg = XD3_SMATCH_FASTEST; | ||
2461 | } | ||
2458 | else if (option_level == 1) { config.smatch_cfg = XD3_SMATCH_FASTEST; } | 2462 | else if (option_level == 1) { config.smatch_cfg = XD3_SMATCH_FASTEST; } |
2459 | else if (option_level <= 5) { config.smatch_cfg = XD3_SMATCH_FAST; } | 2463 | else if (option_level <= 5) { config.smatch_cfg = XD3_SMATCH_FAST; } |
2460 | else if (option_level == 6) { config.smatch_cfg = XD3_SMATCH_DEFAULT; } | 2464 | else if (option_level == 6) { config.smatch_cfg = XD3_SMATCH_DEFAULT; } |
diff --git a/xdelta3/xdelta3-regtest.py b/xdelta3/xdelta3-regtest.py index 928a5f0..8aa03ac 100755 --- a/xdelta3/xdelta3-regtest.py +++ b/xdelta3/xdelta3-regtest.py | |||
@@ -16,12 +16,12 @@ | |||
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 | # Under construction. | 19 | # TODO: Test IOPT (1.5 vs. greedy) |
20 | 20 | ||
21 | # TODO: This is really part test, part performance evaluation suite, and | 21 | # TODO: Start testing window sizes |
22 | # really incomplete. | ||
23 | 22 | ||
24 | # TODO: Test IOPT (1.5 vs. greedy) | 23 | # TODO: Note: xd3_encode_memory is underperforming the command-line |
24 | # at run-speed tests (due to excess memory allocation?). Fix. | ||
25 | 25 | ||
26 | import os, sys, math, re, time, types, array, random | 26 | import os, sys, math, re, time, types, array, random |
27 | import xdelta3main | 27 | import xdelta3main |
@@ -85,7 +85,7 @@ def INPUT_SPEC(rand): | |||
85 | RCSDIR = '/tmp/PRCS_read_copy' | 85 | RCSDIR = '/tmp/PRCS_read_copy' |
86 | #RCSDIR = 'G:/jmacd/PRCS' | 86 | #RCSDIR = 'G:/jmacd/PRCS' |
87 | 87 | ||
88 | SAMPLEDIR = "C:/sample_data/WESNOTH_tmp/tar' | 88 | SAMPLEDIR = "C:/sample_data/WESNOTH_tmp/tar" |
89 | 89 | ||
90 | TMPDIR = '/tmp/xd3regtest.%d' % os.getpid() | 90 | TMPDIR = '/tmp/xd3regtest.%d' % os.getpid() |
91 | 91 | ||
@@ -260,14 +260,15 @@ class RcsFile: | |||
260 | os.stat(self.Verf(v+1)).st_size < MIN_SIZE: | 260 | os.stat(self.Verf(v+1)).st_size < MIN_SIZE: |
261 | continue | 261 | continue |
262 | 262 | ||
263 | result = TimeRun(runnable.Runner(self.Verf(v), | 263 | runnable.SetInputs(self.Verf(v), |
264 | self.Vstr(v), | 264 | self.Vstr(v), |
265 | self.Verf(v+1), | 265 | self.Verf(v+1), |
266 | self.Vstr(v+1))) | 266 | self.Vstr(v+1)) |
267 | print 'testing %s %s: ideal %.3f%%: time %.7f: in %u trials' % \ | 267 | result = TimedTest(runnable) |
268 | print 'testing %s %s: ratio %.3f%%: time %.7f: in %u trials' % \ | ||
268 | (os.path.basename(self.fname), | 269 | (os.path.basename(self.fname), |
269 | self.Vstr(v+1), | 270 | self.Vstr(v+1), |
270 | result.r1.ideal, | 271 | result.r1.ratio, |
271 | result.time.mean, | 272 | result.time.mean, |
272 | result.trials) | 273 | result.trials) |
273 | ntrials.append(result) | 274 | ntrials.append(result) |
@@ -370,9 +371,11 @@ class Bucks: | |||
370 | f.write("%.1f %.1f %.1f %d\n" % (i[0],i[1],i[2],i[3])) | 371 | f.write("%.1f %.1f %.1f %d\n" % (i[0],i[1],i[2],i[3])) |
371 | # | 372 | # |
372 | # | 373 | # |
373 | class TimeRun: | 374 | class TimedTest: |
374 | def __init__(self,runnable, | 375 | def __init__(self,runnable, |
375 | skip_trials=SKIP_TRIALS,min_trials=MIN_TRIALS,max_trials=MAX_TRIALS, | 376 | skip_trials=SKIP_TRIALS, |
377 | min_trials=MIN_TRIALS, | ||
378 | max_trials=MAX_TRIALS, | ||
376 | min_stddev_pct=MIN_STDDEV_PCT): | 379 | min_stddev_pct=MIN_STDDEV_PCT): |
377 | 380 | ||
378 | min_trials = min(min_trials,max_trials) | 381 | min_trials = min(min_trials,max_trials) |
@@ -474,7 +477,6 @@ def RunCommand(args): | |||
474 | raise CommandError(args, 'exited %d' % p) | 477 | raise CommandError(args, 'exited %d' % p) |
475 | 478 | ||
476 | def RunCommandIO(args,infn,outfn): | 479 | def RunCommandIO(args,infn,outfn): |
477 | #print "run command io", args | ||
478 | p = os.fork() | 480 | p = os.fork() |
479 | if p == 0: | 481 | if p == 0: |
480 | os.dup2(os.open(infn,os.O_RDONLY),0) | 482 | os.dup2(os.open(infn,os.O_RDONLY),0) |
@@ -488,7 +490,6 @@ def RunCommandIO(args,infn,outfn): | |||
488 | 490 | ||
489 | def RunXdelta3(args): | 491 | def RunXdelta3(args): |
490 | try: | 492 | try: |
491 | #print 'RUN', args | ||
492 | xdelta3main.main(args) | 493 | xdelta3main.main(args) |
493 | except Exception, e: | 494 | except Exception, e: |
494 | raise CommandError(args, "xdelta3.main exception") | 495 | raise CommandError(args, "xdelta3.main exception") |
@@ -500,15 +501,12 @@ class GzipInfo: | |||
500 | 501 | ||
501 | class Xdelta3Info: | 502 | class Xdelta3Info: |
502 | def __init__(self,target,delta): | 503 | def __init__(self,target,delta): |
503 | # TODO: bug is fixed | ||
504 | self.extcomp = 0 # TODO: I removed some code that called printhdr | ||
505 | self.hdrsize = 0 # to compute these, but printhdr uses stdout (now) | ||
506 | self.tgtsize = os.stat(target).st_size | 504 | self.tgtsize = os.stat(target).st_size |
507 | self.dsize = os.stat(delta).st_size | 505 | self.dsize = os.stat(delta).st_size |
508 | if self.tgtsize > 0: | 506 | if self.tgtsize > 0: |
509 | self.ideal = 100.0 * self.dsize / self.tgtsize; | 507 | self.ratio = 100.0 * self.dsize / self.tgtsize; |
510 | else: | 508 | else: |
511 | self.ideal = 0.0 | 509 | self.ratio = 0.0 |
512 | 510 | ||
513 | class Xdelta3ModInfo: | 511 | class Xdelta3ModInfo: |
514 | def __init__(self,target,delta): | 512 | def __init__(self,target,delta): |
@@ -523,20 +521,20 @@ class Xdelta3ModInfo: | |||
523 | self.tgtsize = len(target) | 521 | self.tgtsize = len(target) |
524 | self.dsize = len(delta) | 522 | self.dsize = len(delta) |
525 | if self.tgtsize > 0: | 523 | if self.tgtsize > 0: |
526 | self.ideal = 100.0 * self.dsize / self.tgtsize; | 524 | self.ratio = 100.0 * self.dsize / self.tgtsize; |
527 | else: | 525 | else: |
528 | self.ideal = 0.0 | 526 | self.ratio = 0.0 |
529 | 527 | ||
530 | class Xdelta3Pair: | 528 | class Xdelta3Pair: |
531 | def __init__(self): | 529 | def __init__(self, extra): |
532 | self.type = 'xdelta3' | 530 | self.type = 'xdelta3' |
533 | self.decode_args = '-dqf' | 531 | self.decode_args = '-dqf' |
534 | self.encode_args = '-eqf' | 532 | self.encode_args = '-eqf' |
535 | self.extra = [] | 533 | self.extra = extra |
536 | self.presrc = '-s' | 534 | self.presrc = '-s' |
537 | self.canrep = 1 | 535 | self.canrep = 1 |
538 | 536 | ||
539 | def Runner(self,old,oldv,new,newv): | 537 | def SetInputs(self,old,oldv,new,newv): |
540 | self.old = old | 538 | self.old = old |
541 | self.oldv = oldv | 539 | self.oldv = oldv |
542 | self.new = new | 540 | self.new = new |
@@ -770,7 +768,7 @@ class RandomTester: | |||
770 | return (TMPDIR + "/big.1", | 768 | return (TMPDIR + "/big.1", |
771 | TMPDIR + "/big.2") | 769 | TMPDIR + "/big.2") |
772 | 770 | ||
773 | def RandomBigRun(self, f1, f2): | 771 | def RandomFileTest(self, f1, f2): |
774 | config = None | 772 | config = None |
775 | if len(self.old_configs) > 0: | 773 | if len(self.old_configs) > 0: |
776 | config = self.old_configs[0] | 774 | config = self.old_configs[0] |
@@ -781,9 +779,9 @@ class RandomTester: | |||
781 | config = self.RandomConfig() | 779 | config = self.RandomConfig() |
782 | #end | 780 | #end |
783 | 781 | ||
784 | runner = Xdelta3Pair() | 782 | runner = Xdelta3Pair([ '-C', ','.join([str(x) for x in config]) ]) |
785 | runner.extra = [ '-C', ','.join([str(x) for x in config]) ] | 783 | runner.SetInputs(f1, 1, f2, 2) |
786 | result = TimeRun(runner.Runner(f1, 1, f2, 2)) | 784 | result = TimedTest(runner) |
787 | 785 | ||
788 | tr = RandomTestResult(self.round_num, | 786 | tr = RandomTestResult(self.round_num, |
789 | config, | 787 | config, |
@@ -900,22 +898,24 @@ class RandomTester: | |||
900 | else: | 898 | else: |
901 | stars = ' *' | 899 | stars = ' *' |
902 | print 'Score: %0.6f %s (%.1f%s%s)' % \ | 900 | print 'Score: %0.6f %s (%.1f%s%s)' % \ |
903 | (test.score, test, s / len(all_r), stars, (len(all_r) > 2) and (' in %d' % len(all_r)) or "") | 901 | (test.score, test, s / len(all_r), stars, |
902 | (len(all_r) > 2) and | ||
903 | (' in %d' % len(all_r)) or "") | ||
904 | #end | 904 | #end |
905 | 905 | ||
906 | return r | 906 | return r |
907 | #end | 907 | #end |
908 | #end | 908 | #end |
909 | 909 | ||
910 | # This tests the raw speed of 0-byte inputs | ||
910 | def RunSpeed(): | 911 | def RunSpeed(): |
911 | # TODO: Start testing window sizes | ||
912 | for L in Decimals(MAX_RUN): | 912 | for L in Decimals(MAX_RUN): |
913 | SetFileSize(RUNFILE, L) | 913 | SetFileSize(RUNFILE, L) |
914 | trx = TimeRun(Xdelta3Run1(RUNFILE)) | 914 | trx = TimedTest(Xdelta3Run1(RUNFILE)) |
915 | ReportSpeed(L,trx,'xdelta3') | 915 | ReportSpeed(L,trx,'xdelta3') |
916 | trm = TimeRun(Xdelta3Mod1(RUNFILE)) | 916 | trm = TimedTest(Xdelta3Mod1(RUNFILE)) |
917 | ReportSpeed(L,trm,'module ') | 917 | ReportSpeed(L,trm,'module ') |
918 | trg = TimeRun(GzipRun1(RUNFILE)) | 918 | trg = TimedTest(GzipRun1(RUNFILE)) |
919 | ReportSpeed(L,trg,'gzip ') | 919 | ReportSpeed(L,trg,'gzip ') |
920 | #end | 920 | #end |
921 | #end | 921 | #end |
@@ -924,15 +924,14 @@ if __name__ == "__main__": | |||
924 | try: | 924 | try: |
925 | RunCommand(['rm', '-rf', TMPDIR]) | 925 | RunCommand(['rm', '-rf', TMPDIR]) |
926 | os.mkdir(TMPDIR) | 926 | os.mkdir(TMPDIR) |
927 | #rcsf = Test() | ||
928 | configs = [] | ||
929 | 927 | ||
930 | # This tests pairwise (date-ordered) performance | ||
931 | #rcsf.PairsByDate(Xdelta3Pair()) | ||
932 | |||
933 | # This tests the raw speed of 0-byte inputs | ||
934 | RunSpeed() | 928 | RunSpeed() |
935 | 929 | ||
930 | # This tests pairwise (date-ordered) performance | ||
931 | #rcsf = Test() | ||
932 | #rcsf.PairsByDate(Xdelta3Pair([])) | ||
933 | |||
934 | configs = [] | ||
936 | 935 | ||
937 | while 0: | 936 | while 0: |
938 | #f1 = '/tmp/big.1' | 937 | #f1 = '/tmp/big.1' |
@@ -944,7 +943,7 @@ if __name__ == "__main__": | |||
944 | f2 = '/tmp/WESNOTH_tmp/wesnoth-1.1.13.tar' | 943 | f2 = '/tmp/WESNOTH_tmp/wesnoth-1.1.13.tar' |
945 | #f1 = '/tmp/big.1' | 944 | #f1 = '/tmp/big.1' |
946 | #f2 = '/tmp/big.2' | 945 | #f2 = '/tmp/big.2' |
947 | test.RandomBigRun(f1, f2) | 946 | test.RandomFileTest(f1, f2) |
948 | #end | 947 | #end |
949 | configs = test.ScoreTests() | 948 | configs = test.ScoreTests() |
950 | 949 | ||
diff --git a/xdelta3/xdelta3-test.py b/xdelta3/xdelta3-test.py index 7ad25dd..2c37030 100755 --- a/xdelta3/xdelta3-test.py +++ b/xdelta3/xdelta3-test.py | |||
@@ -33,7 +33,7 @@ assert len(patch) < len(source) | |||
33 | 33 | ||
34 | print 'encode: adler32 ...' | 34 | print 'encode: adler32 ...' |
35 | result, patch_adler32 = xdelta3.xd3_encode_memory(target, source, 50, | 35 | result, patch_adler32 = xdelta3.xd3_encode_memory(target, source, 50, |
36 | 1<<10) | 36 | xdelta3.XD3_ADLER32) |
37 | 37 | ||
38 | assert result == 0 | 38 | assert result == 0 |
39 | assert len(patch_adler32) < len(source) | 39 | assert len(patch_adler32) < len(source) |
@@ -41,7 +41,7 @@ assert len(patch_adler32) > len(patch) | |||
41 | 41 | ||
42 | print 'encode: secondary ...' | 42 | print 'encode: secondary ...' |
43 | result, patch_djw = xdelta3.xd3_encode_memory(target, source, 50, | 43 | result, patch_djw = xdelta3.xd3_encode_memory(target, source, 50, |
44 | 1<<5) | 44 | xdelta3.XD3_SEC_DJW) |
45 | 45 | ||
46 | assert result == 0 | 46 | assert result == 0 |
47 | # secondary compression doesn't help | 47 | # secondary compression doesn't help |
@@ -111,7 +111,7 @@ for corrupt_pos in range(len(patch_adler32)): | |||
111 | # without adler32 verification, the error may be in the data section which | 111 | # without adler32 verification, the error may be in the data section which |
112 | # in this case is 6 bytes 'target' | 112 | # in this case is 6 bytes 'target' |
113 | result, corrupt = xdelta3.xd3_decode_memory(input, source, len(target), | 113 | result, corrupt = xdelta3.xd3_decode_memory(input, source, len(target), |
114 | 1<<11) | 114 | xdelta3.XD3_ADLER32_NOVER) |
115 | if result == 0: | 115 | if result == 0: |
116 | noverify_count = noverify_count + 1 | 116 | noverify_count = noverify_count + 1 |
117 | #print "got %s" % corrupt | 117 | #print "got %s" % corrupt |
@@ -125,6 +125,22 @@ result, target2 = xdelta3.xd3_decode_memory(zdata, None, len(target)) | |||
125 | assert result == 0 | 125 | assert result == 0 |
126 | assert target == target2 | 126 | assert target == target2 |
127 | 127 | ||
128 | # Test compression level setting via flags. assumes a 9 byte checksum | ||
129 | # and that level 9 steps 2, level 1 steps 15: | ||
130 | # 01234567890123456789012345678901 | ||
131 | # level 1 only indexes 2 checksums "abcdefghi" and "ABCDEFGHI" | ||
132 | # outputs 43 vs. 23 bytes | ||
133 | print 'encode: compression level ...' | ||
134 | |||
135 | source = '_la_la_abcdefghi_la_la_ABCDEFGHI' | ||
136 | target = 'la_la_ABCDEFGH__la_la_abcdefgh__' | ||
137 | |||
138 | result1, level1 = xdelta3.xd3_encode_memory(target, source, 50, xdelta3.XD3_COMPLEVEL_1) | ||
139 | result9, level9 = xdelta3.xd3_encode_memory(target, source, 50, xdelta3.XD3_COMPLEVEL_9) | ||
140 | |||
141 | assert result1 == 0 and result9 == 0 | ||
142 | assert len(level1) > len(level9) | ||
143 | |||
128 | # | 144 | # |
129 | # | 145 | # |
130 | 146 | ||
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index b3fd2ef..32dc8b0 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -94,7 +94,7 @@ | |||
94 | challenge. Search in this file for "black magic", a heuristic. | 94 | challenge. Search in this file for "black magic", a heuristic. |
95 | 95 | ||
96 | 3. STREAM ALIGNMENT. Stream alignment is needed to compress large | 96 | 3. STREAM ALIGNMENT. Stream alignment is needed to compress large |
97 | inputs in constant space. TODO: redocument | 97 | inputs in constant space. See xd3_srcwin_move_point(). |
98 | 98 | ||
99 | 4. WINDOW SELECTION. When the IOPT buffer flushes, in the first call | 99 | 4. WINDOW SELECTION. When the IOPT buffer flushes, in the first call |
100 | to xd3_iopt_finish_encoding containing any kind of copy instruction, | 100 | to xd3_iopt_finish_encoding containing any kind of copy instruction, |
@@ -779,7 +779,7 @@ static const xd3_sec_type djw_sec_type = | |||
779 | * allowing to vary the distribution of single- and | 779 | * allowing to vary the distribution of single- and |
780 | * double-instructions and change the number of near and same copy | 780 | * double-instructions and change the number of near and same copy |
781 | * modes. More exotic tables are only possible by extending this | 781 | * modes. More exotic tables are only possible by extending this |
782 | * code. TODO: experiment with a double-copy instruction. | 782 | * code. |
783 | * | 783 | * |
784 | * For performance reasons, both the parametrized and non-parametrized | 784 | * For performance reasons, both the parametrized and non-parametrized |
785 | * versions of xd3_choose_instruction remain. The parametrized | 785 | * versions of xd3_choose_instruction remain. The parametrized |
@@ -2543,6 +2543,28 @@ xd3_config_stream(xd3_stream *stream, | |||
2543 | return XD3_INTERNAL; | 2543 | return XD3_INTERNAL; |
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | if (config->smatch_cfg == XD3_SMATCH_DEFAULT && | ||
2547 | (stream->flags & XD3_COMPLEVEL_MASK) != 0) | ||
2548 | { | ||
2549 | int level = (stream->flags & XD3_COMPLEVEL_MASK) >> XD3_COMPLEVEL_SHIFT; | ||
2550 | |||
2551 | switch (level) | ||
2552 | { | ||
2553 | case 1: case 2: | ||
2554 | IF_BUILD_FASTEST(*smatcher = __smatcher_fastest; | ||
2555 | break;) | ||
2556 | case 3: case 4: case 5: | ||
2557 | IF_BUILD_FAST(*smatcher = __smatcher_fast; | ||
2558 | break;) | ||
2559 | case 6: | ||
2560 | IF_BUILD_DEFAULT(*smatcher = __smatcher_default; | ||
2561 | break;) | ||
2562 | default: | ||
2563 | IF_BUILD_SLOW(*smatcher = __smatcher_slow; | ||
2564 | break;) | ||
2565 | } | ||
2566 | } | ||
2567 | |||
2546 | return 0; | 2568 | return 0; |
2547 | } | 2569 | } |
2548 | 2570 | ||
@@ -3520,7 +3542,7 @@ xd3_encode_init (xd3_stream *stream) | |||
3520 | * first call to string_match--that way identical or short inputs require no table | 3542 | * first call to string_match--that way identical or short inputs require no table |
3521 | * allocation. */ | 3543 | * allocation. */ |
3522 | 3544 | ||
3523 | // TODO: experiments have to be done!!! | 3545 | /* TODO: need to experiment w/ XD3_DEFAULT_SPREVSZ and large has functions */ |
3524 | if (large_comp) | 3546 | if (large_comp) |
3525 | { | 3547 | { |
3526 | usize_t hash_values = (stream->srcwin_maxsz / stream->smatcher.large_step); | 3548 | usize_t hash_values = (stream->srcwin_maxsz / stream->smatcher.large_step); |
@@ -3532,8 +3554,7 @@ xd3_encode_init (xd3_stream *stream) | |||
3532 | 3554 | ||
3533 | if (small_comp) | 3555 | if (small_comp) |
3534 | { | 3556 | { |
3535 | /* Hard-coded, keeps table small because small matches become inefficient. | 3557 | /* Hard-coded, keeps table small because small matches become inefficient. */ |
3536 | * TODO: verify this stuff. */ | ||
3537 | usize_t hash_values = min(stream->winsize, XD3_DEFAULT_SPREVSZ); | 3558 | usize_t hash_values = min(stream->winsize, XD3_DEFAULT_SPREVSZ); |
3538 | 3559 | ||
3539 | xd3_size_hashtable (stream, | 3560 | xd3_size_hashtable (stream, |
@@ -3931,7 +3952,7 @@ xd3_process_memory (int is_encode, | |||
3931 | 3952 | ||
3932 | if (is_encode) | 3953 | if (is_encode) |
3933 | { | 3954 | { |
3934 | /* TODO: for large inputs, limit window size ... */ | 3955 | /* TODO: for large inputs, limit window size, need to select a default ... */ |
3935 | config.srcwin_maxsz = source_size; | 3956 | config.srcwin_maxsz = source_size; |
3936 | config.winsize = min(input_size, (usize_t) (1<<20)); | 3957 | config.winsize = min(input_size, (usize_t) (1<<20)); |
3937 | } | 3958 | } |
@@ -4117,7 +4138,8 @@ xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | |||
4117 | return low; | 4138 | return low; |
4118 | } | 4139 | } |
4119 | 4140 | ||
4120 | // This should not be >= because srcwin_cksum_pos is the next position to index | 4141 | /* This should not be >= because srcwin_cksum_pos is the next |
4142 | * position to index. */ | ||
4121 | if (low > sr) { | 4143 | if (low > sr) { |
4122 | return (--s0 << 32) | low; | 4144 | return (--s0 << 32) | low; |
4123 | } | 4145 | } |
@@ -4564,8 +4586,6 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4564 | usize_t total = stream->match_fwd + stream->match_back; | 4586 | usize_t total = stream->match_fwd + stream->match_back; |
4565 | 4587 | ||
4566 | /* Correct the variables to remove match_back from the equation. */ | 4588 | /* Correct the variables to remove match_back from the equation. */ |
4567 | // IT'S A BUG! | ||
4568 | |||
4569 | usize_t target_position = stream->input_position - stream->match_back; | 4589 | usize_t target_position = stream->input_position - stream->match_back; |
4570 | usize_t match_length = stream->match_back + stream->match_fwd; | 4590 | usize_t match_length = stream->match_back + stream->match_fwd; |
4571 | xoff_t match_position = stream->match_srcpos - stream->match_back; | 4591 | xoff_t match_position = stream->match_srcpos - stream->match_back; |
@@ -4589,13 +4609,13 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4589 | 4609 | ||
4590 | if (match_end > stream->match_maxaddr) | 4610 | if (match_end > stream->match_maxaddr) |
4591 | { | 4611 | { |
4592 | // Note: per-window | 4612 | /* Note: per-window */ |
4593 | stream->match_maxaddr = match_end; | 4613 | stream->match_maxaddr = match_end; |
4594 | } | 4614 | } |
4595 | 4615 | ||
4596 | if (match_end > stream->maxsrcaddr) | 4616 | if (match_end > stream->maxsrcaddr) |
4597 | { | 4617 | { |
4598 | // Note: across windows | 4618 | /* Note: across windows */ |
4599 | stream->maxsrcaddr = match_end; | 4619 | stream->maxsrcaddr = match_end; |
4600 | } | 4620 | } |
4601 | 4621 | ||
@@ -4927,7 +4947,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4927 | int run_l; | 4947 | int run_l; |
4928 | int ret; | 4948 | int ret; |
4929 | usize_t match_length; | 4949 | usize_t match_length; |
4930 | usize_t match_offset; // Note: "may be unused" warnings are bogus (due to min_match test) | 4950 | usize_t match_offset; /* "may be unused" warnings are bogus (due to min_match test) */ |
4931 | usize_t next_move_point; | 4951 | usize_t next_move_point; |
4932 | 4952 | ||
4933 | /* If there will be no compression due to settings or short input, skip it entirely. */ | 4953 | /* If there will be no compression due to settings or short input, skip it entirely. */ |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 8c11000..cee63cf 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -333,17 +333,27 @@ typedef enum | |||
333 | * only search the source, not the target. */ | 333 | * only search the source, not the target. */ |
334 | XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass algorithm", instead use | 334 | XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass algorithm", instead use |
335 | * greedy matching. Greedy is off by default. */ | 335 | * greedy matching. Greedy is off by default. */ |
336 | |||
337 | /* 4 bits to set the compression level the same as the command-line | ||
338 | * setting -1 through -9 (-0 corresponds to the XD3_NOCOMPRESS flag, | ||
339 | * and is independent of compression level). This is for | ||
340 | * convenience, especially with xd3_encode_memory(). */ | ||
341 | |||
342 | XD3_COMPLEVEL_SHIFT = 20, /* 20 - 24 */ | ||
343 | XD3_COMPLEVEL_MASK = (0xF << XD3_COMPLEVEL_SHIFT), | ||
344 | XD3_COMPLEVEL_1 = (1 << XD3_COMPLEVEL_SHIFT), | ||
345 | XD3_COMPLEVEL_3 = (3 << XD3_COMPLEVEL_SHIFT), | ||
346 | XD3_COMPLEVEL_6 = (6 << XD3_COMPLEVEL_SHIFT), | ||
347 | XD3_COMPLEVEL_9 = (9 << XD3_COMPLEVEL_SHIFT), | ||
348 | |||
336 | } xd3_flags; | 349 | } xd3_flags; |
337 | 350 | ||
338 | /* The values of this enumeration are set in xd3_config using the smatch_cfg variable. It | 351 | /* The values of this enumeration are set in xd3_config using the |
339 | * can be set to slow, fast, soft, or default. The fast and slow setting uses preset, | 352 | * smatch_cfg variable. It can be set to default, slow, fast, etc., |
340 | * hardcoded parameters and the soft setting is accompanied by user-supplied parameters. | 353 | * and soft. */ |
341 | * If the user supplies 'default' the code selects one of the available string matchers. | ||
342 | * Due to compile-time settings (see XD3_SLOW_SMATCHER, XD3_FAST_SMATCHER, | ||
343 | * XD3_SOFT_SMATCHER variables), not all options may be available. */ | ||
344 | typedef enum | 354 | typedef enum |
345 | { | 355 | { |
346 | XD3_SMATCH_DEFAULT = 0, | 356 | XD3_SMATCH_DEFAULT = 0, /* Flags may contain XD3_COMPLEVEL bits, else default. */ |
347 | XD3_SMATCH_SLOW = 1, | 357 | XD3_SMATCH_SLOW = 1, |
348 | XD3_SMATCH_FAST = 2, | 358 | XD3_SMATCH_FAST = 2, |
349 | XD3_SMATCH_FASTEST = 3, | 359 | XD3_SMATCH_FASTEST = 3, |
diff --git a/xdelta3/xdelta3.swig b/xdelta3/xdelta3.swig index 696974f..2ef4306 100644 --- a/xdelta3/xdelta3.swig +++ b/xdelta3/xdelta3.swig | |||
@@ -64,6 +64,30 @@ int xd3_decode_memory (const char *input, | |||
64 | unsigned int max_output, | 64 | unsigned int max_output, |
65 | int flags); | 65 | int flags); |
66 | 66 | ||
67 | int xd3_main_cmdline (int ARGC, char **ARGV); | ||
67 | 68 | ||
68 | 69 | /* Is this the right way? */ | |
69 | int xd3_main_cmdline (int ARGC, char **ARGV); | 70 | enum { |
71 | /*XD3_JUST_HDR,*/ | ||
72 | /*XD3_SKIP_WINDOW,*/ | ||
73 | /*XD3_SKIP_EMIT,*/ | ||
74 | /*XD3_FLUSH,*/ | ||
75 | XD3_SEC_DJW, | ||
76 | XD3_SEC_FGK, | ||
77 | /*XD3_SEC_TYPE,*/ | ||
78 | XD3_SEC_NODATA, | ||
79 | XD3_SEC_NOINST, | ||
80 | XD3_SEC_NOADDR, | ||
81 | /*XD3_SEC_OTHER,*/ | ||
82 | XD3_ADLER32, | ||
83 | XD3_ADLER32_NOVER, | ||
84 | XD3_ALT_CODE_TABLE, | ||
85 | XD3_NOCOMPRESS, | ||
86 | XD3_BEGREEDY, | ||
87 | XD3_COMPLEVEL_SHIFT, | ||
88 | XD3_COMPLEVEL_MASK, | ||
89 | XD3_COMPLEVEL_1, | ||
90 | XD3_COMPLEVEL_3, | ||
91 | XD3_COMPLEVEL_6, | ||
92 | XD3_COMPLEVEL_9, | ||
93 | }; | ||