diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2007-02-01 09:17:19 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2007-02-01 09:17:19 +0000 |
commit | 8748d16e6e5bf741ede89af1940f8291fb1b8046 (patch) | |
tree | 2c9d393e21eb669ae6bdecf931331e1202bffec6 /xdelta3/xdelta3.c | |
parent | 9f465a9db201b97c43d69778eabd222d4fc09fd5 (diff) |
Implmeent xd3_encode_memory() and xd3_decode_memory(), add comments.
Diffstat (limited to 'xdelta3/xdelta3.c')
-rwxr-xr-x | xdelta3/xdelta3.c | 186 |
1 files changed, 143 insertions, 43 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index aaea811..5740777 100755 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -763,9 +763,7 @@ static const xd3_sec_type djw_sec_type = | |||
763 | * allowing to vary the distribution of single- and | 763 | * allowing to vary the distribution of single- and |
764 | * double-instructions and change the number of near and same copy | 764 | * double-instructions and change the number of near and same copy |
765 | * modes. More exotic tables are only possible by extending this | 765 | * modes. More exotic tables are only possible by extending this |
766 | * code, but a detailed experiment would need to be carried out first, | 766 | * code. TODO: experiment with a double-copy instruction. |
767 | * probably using separate code. I would like to experiment with a | ||
768 | * double-copy instruction, for example. | ||
769 | * | 767 | * |
770 | * For performance reasons, both the parametrized and non-parametrized | 768 | * For performance reasons, both the parametrized and non-parametrized |
771 | * versions of xd3_choose_instruction remain. The parametrized | 769 | * versions of xd3_choose_instruction remain. The parametrized |
@@ -1209,8 +1207,8 @@ int xd3_compute_code_table_encoding (xd3_stream *in_stream, const xd3_dinst *cod | |||
1209 | 1207 | ||
1210 | if ((ret = xd3_set_source (& stream, & source))) { goto fail; } | 1208 | if ((ret = xd3_set_source (& stream, & source))) { goto fail; } |
1211 | 1209 | ||
1212 | if ((ret = xd3_encode_completely_stream (& stream, code_string, CODE_TABLE_STRING_SIZE, | 1210 | if ((ret = xd3_encode_stream (& stream, code_string, CODE_TABLE_STRING_SIZE, |
1213 | comp_string, comp_string_size, CODE_TABLE_VCDIFF_SIZE))) { goto fail; } | 1211 | comp_string, comp_string_size, CODE_TABLE_VCDIFF_SIZE))) { goto fail; } |
1214 | 1212 | ||
1215 | fail: | 1213 | fail: |
1216 | 1214 | ||
@@ -1405,7 +1403,7 @@ xd3_apply_table_encoding (xd3_stream *in_stream, const uint8_t *data, usize_t si | |||
1405 | 1403 | ||
1406 | if ((ret = xd3_config_stream (& stream, NULL)) || | 1404 | if ((ret = xd3_config_stream (& stream, NULL)) || |
1407 | (ret = xd3_set_source (& stream, & source)) || | 1405 | (ret = xd3_set_source (& stream, & source)) || |
1408 | (ret = xd3_decode_completely_stream (& stream, data, size, code_string, & code_size, sizeof (code_string)))) | 1406 | (ret = xd3_decode_stream (& stream, data, size, code_string, & code_size, sizeof (code_string)))) |
1409 | { | 1407 | { |
1410 | in_stream->msg = stream.msg; | 1408 | in_stream->msg = stream.msg; |
1411 | goto fail; | 1409 | goto fail; |
@@ -3809,17 +3807,15 @@ xd3_encode_input (xd3_stream *stream) | |||
3809 | Client convenience functions | 3807 | Client convenience functions |
3810 | ******************************************************************************************/ | 3808 | ******************************************************************************************/ |
3811 | 3809 | ||
3812 | /* This function invokes either encode or decode to and from in-memory arrays. The output array | ||
3813 | * must be large enough to hold the output or else ENOSPC is returned. */ | ||
3814 | static int | 3810 | static int |
3815 | xd3_process_completely_stream (xd3_stream *stream, | 3811 | xd3_process_stream (xd3_stream *stream, |
3816 | int (*func) (xd3_stream *), | 3812 | int (*func) (xd3_stream *), |
3817 | int close_stream, | 3813 | int close_stream, |
3818 | const uint8_t *input, | 3814 | const uint8_t *input, |
3819 | usize_t input_size, | 3815 | usize_t input_size, |
3820 | uint8_t *output, | 3816 | uint8_t *output, |
3821 | usize_t *output_size, | 3817 | usize_t *output_size, |
3822 | usize_t avail_size) | 3818 | usize_t output_size_max) |
3823 | { | 3819 | { |
3824 | (*output_size) = 0; | 3820 | (*output_size) = 0; |
3825 | 3821 | ||
@@ -3842,13 +3838,17 @@ xd3_process_completely_stream (xd3_stream *stream, | |||
3842 | stream->msg = "stream requires source input"; | 3838 | stream->msg = "stream requires source input"; |
3843 | return XD3_INTERNAL; | 3839 | return XD3_INTERNAL; |
3844 | } | 3840 | } |
3845 | case 0: /* there is no plain "success" return for xd3_encode/decode */ | 3841 | case 0: |
3846 | XD3_ASSERT (ret != 0); | 3842 | { |
3843 | /* xd3_encode_input/xd3_decode_input never return 0 */ | ||
3844 | stream->msg = "invalid return: 0"; | ||
3845 | return XD3_INTERNAL; | ||
3846 | } | ||
3847 | default: | 3847 | default: |
3848 | return ret; | 3848 | return ret; |
3849 | } | 3849 | } |
3850 | 3850 | ||
3851 | if (*output_size + stream->avail_out > avail_size) | 3851 | if (*output_size + stream->avail_out > output_size_max) |
3852 | { | 3852 | { |
3853 | stream->msg = "insufficient output space"; | 3853 | stream->msg = "insufficient output space"; |
3854 | return ENOSPC; | 3854 | return ENOSPC; |
@@ -3864,34 +3864,129 @@ xd3_process_completely_stream (xd3_stream *stream, | |||
3864 | return (close_stream == 0) ? 0 : xd3_close_stream (stream); | 3864 | return (close_stream == 0) ? 0 : xd3_close_stream (stream); |
3865 | } | 3865 | } |
3866 | 3866 | ||
3867 | static int | ||
3868 | xd3_process_memory (int (*func) (xd3_stream *), | ||
3869 | int close_stream, | ||
3870 | const uint8_t *input, | ||
3871 | usize_t input_size, | ||
3872 | const uint8_t *source, | ||
3873 | usize_t source_size, | ||
3874 | uint8_t *output, | ||
3875 | usize_t *output_size, | ||
3876 | usize_t output_size_max, | ||
3877 | int flags) { | ||
3878 | xd3_stream stream; | ||
3879 | xd3_config config; | ||
3880 | xd3_source src; | ||
3881 | int ret; | ||
3882 | |||
3883 | /* TODO: for small inputs, the xd3_stream could be configured to allocate MUCH less | ||
3884 | * memory. Most of the allocations sizes are defaulted (see xdelta3.h), and assume | ||
3885 | * large inputs. */ | ||
3886 | memset (& stream, 0, sizeof (stream)); | ||
3887 | memset (& config, 0, sizeof (config)); | ||
3888 | |||
3889 | config.flags = flags; | ||
3890 | config.srcwin_maxsz = source_size; | ||
3891 | config.winsize = input_size; | ||
3892 | |||
3893 | if ((ret = xd3_config_stream (&stream, &config)) != 0) | ||
3894 | { | ||
3895 | goto exit; | ||
3896 | } | ||
3897 | |||
3898 | if (source != NULL) | ||
3899 | { | ||
3900 | memset (& src, 0, sizeof (src)); | ||
3901 | src.size = source_size; | ||
3902 | src.blksize = source_size; | ||
3903 | src.onblk = source_size; | ||
3904 | src.curblk = source; | ||
3905 | src.curblkno = 0; | ||
3906 | |||
3907 | if ((ret = xd3_set_source (&stream, &src)) != 0) | ||
3908 | { | ||
3909 | goto exit; | ||
3910 | } | ||
3911 | } | ||
3912 | |||
3913 | if ((ret = xd3_process_stream (& stream, | ||
3914 | func, 1, | ||
3915 | input, input_size, | ||
3916 | output, | ||
3917 | output_size, | ||
3918 | output_size_max)) != 0) | ||
3919 | { | ||
3920 | goto exit; | ||
3921 | } | ||
3922 | |||
3923 | exit: | ||
3924 | xd3_free_stream(&stream); | ||
3925 | return ret; | ||
3926 | } | ||
3927 | |||
3867 | int | 3928 | int |
3868 | xd3_decode_completely_stream (xd3_stream *stream, | 3929 | xd3_decode_stream (xd3_stream *stream, |
3869 | const uint8_t *input, | 3930 | const uint8_t *input, |
3870 | usize_t input_size, | 3931 | usize_t input_size, |
3871 | uint8_t *output, | 3932 | uint8_t *output, |
3872 | usize_t *output_size, | 3933 | usize_t *output_size, |
3873 | usize_t avail_size) | 3934 | usize_t output_size_max) |
3874 | { | 3935 | { |
3875 | return xd3_process_completely_stream (stream, & xd3_decode_input, 1, | 3936 | return xd3_process_stream (stream, & xd3_decode_input, 1, |
3876 | input, input_size, | 3937 | input, input_size, |
3877 | output, output_size, avail_size); | 3938 | output, output_size, output_size_max); |
3878 | } | 3939 | } |
3879 | 3940 | ||
3941 | int | ||
3942 | xd3_decode_memory (const uint8_t *input, | ||
3943 | usize_t input_size, | ||
3944 | const uint8_t *source, | ||
3945 | usize_t source_size, | ||
3946 | uint8_t *output, | ||
3947 | usize_t *output_size, | ||
3948 | usize_t output_size_max, | ||
3949 | int flags) { | ||
3950 | return xd3_process_memory (& xd3_decode_input, 1, | ||
3951 | input, input_size, | ||
3952 | source, source_size, | ||
3953 | output, output_size, output_size_max, | ||
3954 | flags); | ||
3955 | } | ||
3956 | |||
3957 | |||
3880 | #if XD3_ENCODER | 3958 | #if XD3_ENCODER |
3881 | int | 3959 | int |
3882 | xd3_encode_completely_stream (xd3_stream *stream, | 3960 | xd3_encode_stream (xd3_stream *stream, |
3883 | const uint8_t *input, | 3961 | const uint8_t *input, |
3884 | usize_t input_size, | 3962 | usize_t input_size, |
3885 | uint8_t *output, | 3963 | uint8_t *output, |
3886 | usize_t *output_size, | 3964 | usize_t *output_size, |
3887 | usize_t avail_size) | 3965 | usize_t output_size_max) |
3888 | { | 3966 | { |
3889 | return xd3_process_completely_stream (stream, & xd3_encode_input, 1, | 3967 | return xd3_process_stream (stream, & xd3_encode_input, 1, |
3890 | input, input_size, | 3968 | input, input_size, |
3891 | output, output_size, avail_size); | 3969 | output, output_size, output_size_max); |
3970 | } | ||
3971 | |||
3972 | int | ||
3973 | xd3_encode_memory (const uint8_t *input, | ||
3974 | usize_t input_size, | ||
3975 | const uint8_t *source, | ||
3976 | usize_t source_size, | ||
3977 | uint8_t *output, | ||
3978 | usize_t *output_size, | ||
3979 | usize_t output_size_max, | ||
3980 | int flags) { | ||
3981 | return xd3_process_memory (& xd3_encode_input, 1, | ||
3982 | input, input_size, | ||
3983 | source, source_size, | ||
3984 | output, output_size, output_size_max, | ||
3985 | flags); | ||
3892 | } | 3986 | } |
3893 | #endif | 3987 | #endif |
3894 | 3988 | ||
3989 | |||
3895 | /****************************************************************************************** | 3990 | /****************************************************************************************** |
3896 | String matching helpers | 3991 | String matching helpers |
3897 | ******************************************************************************************/ | 3992 | ******************************************************************************************/ |
@@ -3996,7 +4091,7 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
3996 | stream->srcwin_cksum_pos = stream->maxsrcaddr; | 4091 | stream->srcwin_cksum_pos = stream->maxsrcaddr; |
3997 | } | 4092 | } |
3998 | 4093 | ||
3999 | if (logical_input_cksum_pos < stream->srcwin_cksum_pos) | 4094 | if (logical_input_cksum_pos < stream->srcwin_cksum_pos) |
4000 | { | 4095 | { |
4001 | logical_input_cksum_pos = stream->srcwin_cksum_pos; | 4096 | logical_input_cksum_pos = stream->srcwin_cksum_pos; |
4002 | } | 4097 | } |
@@ -4004,7 +4099,7 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4004 | /* Advance an extra srcwin_size bytes */ | 4099 | /* Advance an extra srcwin_size bytes */ |
4005 | logical_input_cksum_pos += stream->srcwin_size; | 4100 | logical_input_cksum_pos += stream->srcwin_size; |
4006 | 4101 | ||
4007 | IF_DEBUG1 (P(RINT "[srcwin_move_point] T=%"Q"u S=%"Q"u/%"Q"u\n", | 4102 | IF_DEBUG1 (P(RINT "[srcwin_move_point] T=%"Q"u S=%"Q"u/%"Q"u\n", |
4008 | stream->total_in + stream->input_position, | 4103 | stream->total_in + stream->input_position, |
4009 | stream->srcwin_cksum_pos, | 4104 | stream->srcwin_cksum_pos, |
4010 | logical_input_cksum_pos)); | 4105 | logical_input_cksum_pos)); |
@@ -4038,6 +4133,9 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4038 | diff = logical_input_cksum_pos - stream->srcwin_cksum_pos; | 4133 | diff = logical_input_cksum_pos - stream->srcwin_cksum_pos; |
4039 | onblk = min(blkoff + diff, onblk); | 4134 | onblk = min(blkoff + diff, onblk); |
4040 | 4135 | ||
4136 | /* TODO: This block needs to be included in the template pass... duh. | ||
4137 | */ | ||
4138 | |||
4041 | /* Note: I experimented with rewriting this block to use LARGE_CKSUM_UPDATE() | 4139 | /* Note: I experimented with rewriting this block to use LARGE_CKSUM_UPDATE() |
4042 | * instead of recalculating the cksum every N bytes. It seemed to make performance | 4140 | * instead of recalculating the cksum every N bytes. It seemed to make performance |
4043 | * worse. */ | 4141 | * worse. */ |
@@ -4066,7 +4164,7 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4066 | 4164 | ||
4067 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit but the hash | 4165 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit but the hash |
4068 | * table for source-offsets is 32bit. */ | 4166 | * table for source-offsets is 32bit. */ |
4069 | static xoff_t | 4167 | static xoff_t |
4070 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | 4168 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) |
4071 | { | 4169 | { |
4072 | xoff_t scp = stream->srcwin_cksum_pos; | 4170 | xoff_t scp = stream->srcwin_cksum_pos; |
@@ -4179,7 +4277,7 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
4179 | greedy_or_not = stream->unencoded_offset; | 4277 | greedy_or_not = stream->unencoded_offset; |
4180 | } | 4278 | } |
4181 | 4279 | ||
4182 | 4280 | ||
4183 | 4281 | ||
4184 | /* Backward target match limit. */ | 4282 | /* Backward target match limit. */ |
4185 | XD3_ASSERT (stream->input_position >= greedy_or_not); | 4283 | XD3_ASSERT (stream->input_position >= greedy_or_not); |
@@ -4295,7 +4393,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4295 | { | 4393 | { |
4296 | break; | 4394 | break; |
4297 | } | 4395 | } |
4298 | 4396 | ||
4299 | /* could be a XD3_GETSRCBLK failure. */ | 4397 | /* could be a XD3_GETSRCBLK failure. */ |
4300 | return ret; | 4398 | return ret; |
4301 | } | 4399 | } |
@@ -4387,7 +4485,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4387 | 4485 | ||
4388 | /* Correct the variables to remove match_back from the equation. */ | 4486 | /* Correct the variables to remove match_back from the equation. */ |
4389 | // IT'S A BUG! | 4487 | // IT'S A BUG! |
4390 | 4488 | ||
4391 | usize_t target_position = stream->input_position - stream->match_back; | 4489 | usize_t target_position = stream->input_position - stream->match_back; |
4392 | usize_t match_length = stream->match_back + stream->match_fwd; | 4490 | usize_t match_length = stream->match_back + stream->match_fwd; |
4393 | xoff_t match_position = stream->match_srcpos - stream->match_back; | 4491 | xoff_t match_position = stream->match_srcpos - stream->match_back; |
@@ -4554,6 +4652,8 @@ xd3_check_smatch (const uint8_t *ref0, const uint8_t *inp0, | |||
4554 | * comparison to zlib) in order to support the PROMOTE decision, which is to prefer the | 4652 | * comparison to zlib) in order to support the PROMOTE decision, which is to prefer the |
4555 | * most recently used matching address of a certain string to aid the VCDIFF same cache. | 4653 | * most recently used matching address of a certain string to aid the VCDIFF same cache. |
4556 | * | 4654 | * |
4655 | * --- TODO: declare the PROMOTE experiment a failure -- remove the extra LIST -- | ||
4656 | * | ||
4557 | * Weak reasoning? it's time to modularize this routine...? Let's say the PROMOTE | 4657 | * Weak reasoning? it's time to modularize this routine...? Let's say the PROMOTE |
4558 | * feature supported by this slow data structure contributes around 2% improvement in | 4658 | * feature supported by this slow data structure contributes around 2% improvement in |
4559 | * compressed size, is there a better code table that doesn't use the SAME address cache, | 4659 | * compressed size, is there a better code table that doesn't use the SAME address cache, |