summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xxdelta3/examples/Makefile7
-rwxr-xr-xxdelta3/examples/small_page_test.c135
-rw-r--r--xdelta3/xdelta3-djw.h12
-rw-r--r--xdelta3/xdelta3.c6
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 @@
1CFLAGS = -g -O2 -Wall -I .. 1CFLAGS = -g -Wall -I ..
2 2
3SOURCES = small_page_test.c 3SOURCES = small_page_test.c
4 4
5small_page_test: $(SOURCES) 5small_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
8clean:
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
27static int max_allocated = 0;
28
25void* 29void*
26process_alloc (void* opaque, usize_t items, usize_t size) 30process_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
46void
47process_free (void* opaque, void *ptr)
48{
49}
50
42int 51int
43process_page (int is_encode, 52process_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)
2361static const char* 2361static const char*
2362xd3_rtype_to_string (xd3_rtype type, int print_mode) 2362xd3_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