diff options
Diffstat (limited to 'xdelta3')
-rwxr-xr-x | xdelta3/examples/Makefile | 7 | ||||
-rwxr-xr-x | xdelta3/examples/small_page_test.c | 135 | ||||
-rw-r--r-- | xdelta3/xdelta3-djw.h | 12 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 6 |
4 files changed, 102 insertions, 58 deletions
diff --git a/xdelta3/examples/Makefile b/xdelta3/examples/Makefile index 657e08a..dd1f036 100755 --- a/xdelta3/examples/Makefile +++ b/xdelta3/examples/Makefile | |||
@@ -1,6 +1,9 @@ | |||
1 | CFLAGS = -g -O2 -Wall -I .. | 1 | CFLAGS = -g -Wall -I .. |
2 | 2 | ||
3 | SOURCES = small_page_test.c | 3 | SOURCES = small_page_test.c |
4 | 4 | ||
5 | small_page_test: $(SOURCES) | 5 | small_page_test: $(SOURCES) |
6 | $(CC) $(CFLAGS) small_page_test.c -o small_page_test -DXD3_USE_LARGEFILE64=1 -DSECONDARY_DJW=1 | 6 | $(CC) $(CFLAGS) small_page_test.c -o small_page_test -DXD3_USE_LARGEFILE64=1 -DSECONDARY_DJW=1 -DXD3_DEBUG=1 |
7 | |||
8 | clean: | ||
9 | rm -f *.exe *.stackdump | ||
diff --git a/xdelta3/examples/small_page_test.c b/xdelta3/examples/small_page_test.c index 2d9fb1c..714fd6e 100755 --- a/xdelta3/examples/small_page_test.c +++ b/xdelta3/examples/small_page_test.c | |||
@@ -2,17 +2,19 @@ | |||
2 | 2 | ||
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | 4 | ||
5 | #define SPACE_MAX 32768 | ||
6 | #define PAGE_SIZE 4096 | 5 | #define PAGE_SIZE 4096 |
7 | #define OUTPUT_MAX 1024 | ||
8 | #define IOPT_SIZE 1024 | ||
9 | #define XD3_ALLOCSIZE 256 | ||
10 | 6 | ||
11 | // typedef void* (xd3_alloc_func) (void *opaque, | 7 | #define SPACE_MAX 131072 // how much memory per process |
12 | // usize_t items, | 8 | #define OUTPUT_MAX 1024 // max size for output |
13 | // usize_t size); | 9 | #define XD3_ALLOCSIZE 256 // internal size for various buffers |
14 | // typedef void (xd3_free_func) (void *opaque, | 10 | #define IOPT_SIZE 128 // instruction buffer |
15 | // void *address); | 11 | |
12 | // SPACE_MAX of 32K is sufficient for most inputs with XD3_COMPLEVEL_1 | ||
13 | // XD3_COMPLEVEL_9 requires about 4x more space than XD3_COMPLEVEL_1 | ||
14 | |||
15 | // TODO: experimental PROMOTE code in the encoder is using 16 bytes | ||
16 | // per entry in a table, where 4 bytes are sufficient w/o this | ||
17 | // (unimpressive) feature. Remove PROMOTE code. | ||
16 | 18 | ||
17 | #include "xdelta3.h" | 19 | #include "xdelta3.h" |
18 | #include "xdelta3.c" | 20 | #include "xdelta3.c" |
@@ -22,6 +24,8 @@ typedef struct _context { | |||
22 | int allocated; | 24 | int allocated; |
23 | } context_t; | 25 | } context_t; |
24 | 26 | ||
27 | static int max_allocated = 0; | ||
28 | |||
25 | void* | 29 | void* |
26 | process_alloc (void* opaque, usize_t items, usize_t size) | 30 | process_alloc (void* opaque, usize_t items, usize_t size) |
27 | { | 31 | { |
@@ -39,6 +43,11 @@ process_alloc (void* opaque, usize_t items, usize_t size) | |||
39 | return ret; | 43 | return ret; |
40 | } | 44 | } |
41 | 45 | ||
46 | void | ||
47 | process_free (void* opaque, void *ptr) | ||
48 | { | ||
49 | } | ||
50 | |||
42 | int | 51 | int |
43 | process_page (int is_encode, | 52 | process_page (int is_encode, |
44 | int (*func) (xd3_stream *), | 53 | int (*func) (xd3_stream *), |
@@ -49,46 +58,61 @@ process_page (int is_encode, | |||
49 | usize_t *output_size, | 58 | usize_t *output_size, |
50 | usize_t output_size_max, | 59 | usize_t output_size_max, |
51 | int flags) { | 60 | int flags) { |
52 | xd3_stream *stream; | 61 | |
53 | xd3_config *config; | 62 | /* On my x86 this is 1072 of objects on the stack */ |
54 | xd3_source *src; | 63 | xd3_stream stream; |
55 | context_t *ctx = calloc(OUTPUT_MAX, 1); | 64 | xd3_config config; |
65 | xd3_source src; | ||
66 | context_t *ctx = calloc(SPACE_MAX, 1); | ||
56 | int ret; | 67 | int ret; |
57 | 68 | ||
58 | ctx->buffer = ((char*)ctx) + sizeof(*ctx); | 69 | if (ctx == NULL) |
70 | { | ||
71 | printf("calloc failed\n"); | ||
72 | return -1; | ||
73 | } | ||
74 | |||
75 | ctx->buffer = (uint8_t*)ctx; | ||
59 | ctx->allocated = sizeof(*ctx); | 76 | ctx->allocated = sizeof(*ctx); |
60 | 77 | ||
61 | stream = process_alloc (ctx, 1, sizeof(*stream)); | 78 | config.flags = flags; |
62 | config = process_alloc (ctx, 1, sizeof(*config)); | 79 | config.winsize = PAGE_SIZE; |
63 | src = process_alloc (ctx, 1, sizeof(*src)); | 80 | config.sprevsz = PAGE_SIZE; |
64 | 81 | config.srcwin_maxsz = PAGE_SIZE; | |
65 | config->flags = flags; | 82 | config.iopt_size = IOPT_SIZE; |
66 | config->winsize = PAGE_SIZE; | 83 | config.alloc = &process_alloc; |
67 | config->sprevsz = PAGE_SIZE; | 84 | config.freef = &process_free; |
68 | config->srcwin_maxsz = PAGE_SIZE; | 85 | config.opaque = (void*) ctx; |
69 | config->iopt_size = IOPT_SIZE; | 86 | |
70 | config->alloc = &process_alloc; | 87 | src.size = PAGE_SIZE; |
71 | config->opaque = (void*) ctx; | 88 | src.blksize = PAGE_SIZE; |
72 | 89 | src.onblk = PAGE_SIZE; | |
73 | src->size = PAGE_SIZE; | 90 | src.curblk = source; |
74 | src->blksize = PAGE_SIZE; | 91 | src.curblkno = 0; |
75 | src->onblk = PAGE_SIZE; | 92 | |
76 | src->curblk = source; | 93 | if ((ret = xd3_config_stream (&stream, &config)) != 0 || |
77 | src->curblkno = 0; | 94 | (ret = xd3_set_source (&stream, &src)) != 0 || |
78 | |||
79 | if ((ret = xd3_config_stream (stream, config)) != 0 || | ||
80 | (ret = xd3_set_source (stream, src)) != 0 || | ||
81 | (ret = xd3_process_stream (is_encode, | 95 | (ret = xd3_process_stream (is_encode, |
82 | stream, | 96 | &stream, |
83 | func, 1, | 97 | func, 1, |
84 | input, PAGE_SIZE, | 98 | input, input_size, |
85 | output, output_size, | 99 | output, output_size, |
86 | output_size_max)) != 0) | 100 | output_size_max)) != 0) |
87 | { | 101 | { |
88 | // (void) 0; | 102 | if (stream.msg != NULL) |
103 | { | ||
104 | fprintf(stderr, "stream message: %s\n", stream.msg); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | xd3_free_stream (&stream); | ||
109 | if (max_allocated < ctx->allocated) | ||
110 | { | ||
111 | max_allocated = ctx->allocated; | ||
112 | fprintf(stderr, "max allocated %d\n", max_allocated); | ||
89 | } | 113 | } |
90 | 114 | ||
91 | xd3_free_stream (stream); | 115 | free(ctx); |
92 | return ret; | 116 | return ret; |
93 | } | 117 | } |
94 | 118 | ||
@@ -97,14 +121,14 @@ int test(int stride, int encode_flags) | |||
97 | uint8_t frompg[PAGE_SIZE]; | 121 | uint8_t frompg[PAGE_SIZE]; |
98 | uint8_t topg[PAGE_SIZE]; | 122 | uint8_t topg[PAGE_SIZE]; |
99 | uint8_t output[OUTPUT_MAX]; | 123 | uint8_t output[OUTPUT_MAX]; |
100 | uint8_t reout[OUTPUT_MAX]; | 124 | uint8_t reout[PAGE_SIZE]; |
101 | usize_t output_size; | 125 | usize_t output_size; |
102 | usize_t re_size; | 126 | usize_t re_size; |
103 | int i, j, ret; | 127 | int i, j, ret; |
104 | 128 | ||
105 | for (i = 0; i < PAGE_SIZE; i++) | 129 | for (i = 0; i < PAGE_SIZE; i++) |
106 | { | 130 | { |
107 | topg[i] = frompg[i] = lrand48(); | 131 | topg[i] = frompg[i] = (rand() >> 3 ^ rand() >> 6 ^ rand() >> 9); |
108 | } | 132 | } |
109 | 133 | ||
110 | // change 1 byte every stride | 134 | // change 1 byte every stride |
@@ -122,26 +146,38 @@ int test(int stride, int encode_flags) | |||
122 | &output_size, OUTPUT_MAX, | 146 | &output_size, OUTPUT_MAX, |
123 | encode_flags)) != 0) | 147 | encode_flags)) != 0) |
124 | { | 148 | { |
149 | fprintf (stderr, "encode failed: stride %u flags 0x%x\n", stride, encode_flags); | ||
125 | return ret; | 150 | return ret; |
126 | } | 151 | } |
127 | 152 | ||
128 | if ((ret = process_page (1, xd3_decode_input, | 153 | if ((ret = process_page (0, xd3_decode_input, |
129 | output, output_size, | 154 | output, output_size, |
130 | frompg, reout, | 155 | frompg, reout, |
131 | &re_size, PAGE_SIZE, | 156 | &re_size, PAGE_SIZE, |
132 | 0)) != 0) | 157 | 0)) != 0) |
133 | { | 158 | { |
159 | fprintf (stderr, "decode failed: stride %u output_size %u flags 0x%x\n", | ||
160 | stride, output_size, encode_flags); | ||
134 | return ret; | 161 | return ret; |
135 | } | 162 | } |
136 | 163 | ||
137 | if (output_size > OUTPUT_MAX || re_size != PAGE_SIZE) | 164 | if (output_size > OUTPUT_MAX || re_size != PAGE_SIZE) |
138 | { | 165 | { |
139 | printf ("internal error\n"); | 166 | fprintf (stderr, "internal error: %u != %u\n", output_size, re_size); |
140 | return -1; | 167 | return -1; |
141 | } | 168 | } |
142 | 169 | ||
143 | printf("stride %d flags 0x%x size %u ", stride, encode_flags, output_size); | 170 | for (i = 0; i < PAGE_SIZE; i++) |
144 | printf("%s\n", (ret == 0) ? "OK" : "FAIL"); | 171 | { |
172 | if (reout[i] != topg[i]) | ||
173 | { | ||
174 | fprintf (stderr, "encode-decode error: position %d\n", i); | ||
175 | return -1; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | fprintf(stderr, "stride %d flags 0x%x size %u ", stride, encode_flags, output_size); | ||
180 | fprintf(stderr, "%s\n", (ret == 0) ? "OK" : "FAIL"); | ||
145 | 181 | ||
146 | return 0; | 182 | return 0; |
147 | } | 183 | } |
@@ -150,20 +186,15 @@ int main() | |||
150 | { | 186 | { |
151 | int stride; | 187 | int stride; |
152 | int level; | 188 | int level; |
153 | int ret; | ||
154 | 189 | ||
155 | for (level = 1; level < 10; level = (level == 1 ? 3 : level + 3)) | 190 | for (level = 1; level < 10; level = (level == 1 ? 3 : level + 3)) |
156 | { | 191 | { |
157 | int lflag = level << XD3_COMPLEVEL_SHIFT; | 192 | int lflag = level << XD3_COMPLEVEL_SHIFT; |
158 | 193 | ||
159 | for (stride = 0; stride <= PAGE_SIZE; stride += PAGE_SIZE / 64) | 194 | for (stride = 2; stride <= PAGE_SIZE; stride += 2) |
160 | { | 195 | { |
161 | if ((ret = test(stride, lflag)) || | 196 | test(stride, lflag); |
162 | (ret = test(stride, lflag | XD3_ADLER32)) || | 197 | test(stride, lflag | XD3_SEC_DJW); |
163 | (ret = test(stride, lflag | XD3_SEC_DJW))) | ||
164 | { | ||
165 | return ret; | ||
166 | } | ||
167 | } | 198 | } |
168 | } | 199 | } |
169 | 200 | ||
diff --git a/xdelta3/xdelta3-djw.h b/xdelta3/xdelta3-djw.h index deff7cb..385775a 100644 --- a/xdelta3/xdelta3-djw.h +++ b/xdelta3/xdelta3-djw.h | |||
@@ -911,8 +911,15 @@ xd3_real_encode_huff (xd3_stream *stream, | |||
911 | DJW_SECTORSZ_BITS, (sector_size/DJW_SECTORSZ_MULT)-1))) { goto failure; } | 911 | DJW_SECTORSZ_BITS, (sector_size/DJW_SECTORSZ_MULT)-1))) { goto failure; } |
912 | 912 | ||
913 | /* Dynamic allocation. */ | 913 | /* Dynamic allocation. */ |
914 | if (gbest == NULL) { gbest = xd3_alloc (stream, gbest_max, 1); } | 914 | if (gbest == NULL) |
915 | if (gbest_mtf == NULL) { gbest_mtf = xd3_alloc (stream, gbest_max, 1); } | 915 | { |
916 | if ((gbest = xd3_alloc (stream, gbest_max, 1)) == NULL) { ret = ENOMEM; goto failure; } | ||
917 | } | ||
918 | |||
919 | if (gbest_mtf == NULL) | ||
920 | { | ||
921 | if ((gbest_mtf = xd3_alloc (stream, gbest_max, 1)) == NULL) { ret = ENOMEM; goto failure; } | ||
922 | } | ||
916 | 923 | ||
917 | /* OPT: Some of the inner loops can be optimized, as shown in bzip2 */ | 924 | /* OPT: Some of the inner loops can be optimized, as shown in bzip2 */ |
918 | 925 | ||
@@ -1005,6 +1012,7 @@ xd3_real_encode_huff (xd3_stream *stream, | |||
1005 | if (gcost[gp] < best) { best = gcost[gp]; winner = gp; } | 1012 | if (gcost[gp] < best) { best = gcost[gp]; winner = gp; } |
1006 | } | 1013 | } |
1007 | 1014 | ||
1015 | XD3_ASSERT(gbest_no < gbest_max); | ||
1008 | gbest[gbest_no++] = winner; | 1016 | gbest[gbest_no++] = winner; |
1009 | IF_DEBUG1 (gcount[winner] += 1); | 1017 | IF_DEBUG1 (gcount[winner] += 1); |
1010 | 1018 | ||
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 5535d07..7042903 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -2357,7 +2357,7 @@ xd3_free_stream (xd3_stream *stream) | |||
2357 | memset (stream, 0, sizeof (xd3_stream)); | 2357 | memset (stream, 0, sizeof (xd3_stream)); |
2358 | } | 2358 | } |
2359 | 2359 | ||
2360 | #if (VCDIFF_TOOLS) | 2360 | #if (XD3_DEBUG > 1 || VCDIFF_TOOLS) |
2361 | static const char* | 2361 | static const char* |
2362 | xd3_rtype_to_string (xd3_rtype type, int print_mode) | 2362 | xd3_rtype_to_string (xd3_rtype type, int print_mode) |
2363 | { | 2363 | { |
@@ -2424,7 +2424,7 @@ xd3_config_stream(xd3_stream *stream, | |||
2424 | } | 2424 | } |
2425 | else | 2425 | else |
2426 | { | 2426 | { |
2427 | stream->iopt_size = XD3_DEFAULT_IOPT_SIZE; | 2427 | stream->iopt_size = config->iopt_size; |
2428 | } | 2428 | } |
2429 | 2429 | ||
2430 | stream->getblk = config->getblk; | 2430 | stream->getblk = config->getblk; |
@@ -3133,10 +3133,12 @@ xd3_iopt_get_slot (xd3_stream *stream, xd3_rinst** iptr) | |||
3133 | if (stream->iopt_unlimited) | 3133 | if (stream->iopt_unlimited) |
3134 | { | 3134 | { |
3135 | int elts = XD3_ALLOCSIZE / sizeof(xd3_rinst); | 3135 | int elts = XD3_ALLOCSIZE / sizeof(xd3_rinst); |
3136 | |||
3136 | if ((ret = xd3_alloc_iopt (stream, elts))) | 3137 | if ((ret = xd3_alloc_iopt (stream, elts))) |
3137 | { | 3138 | { |
3138 | return ret; | 3139 | return ret; |
3139 | } | 3140 | } |
3141 | |||
3140 | stream->iopt_size += elts; | 3142 | stream->iopt_size += elts; |
3141 | } | 3143 | } |
3142 | else | 3144 | else |