Re: [PATCH] write_sha1_file(): Perform Z_FULL_FLUSH between header and data
- From
Sergey Vlasov <vsu@altlinux.ru>
- Date
- Mar 8, 2006, 14:17 UTC
- Message-ID
- <20060308141709.GB9555@procyon.home>
- In-Reply-To
- <7vhd69i4ep.fsf@assigned-by-dhcp.cox.net>
On Wed, Mar 08, 2006 at 03:04:14AM -0800, Junio C Hamano wrote:
Show 12 quoted lines
> Sergey Vlasov <vsu@altlinux.ru> writes: > > However, a straight reuse still will not be possible, because > > sha1write_compressed() uses deflateInit(&stream, Z_DEFAULT_COMPRESSION), > > which writes zlib headers around the deflate stream, and the zlib footer > > contains adler32 checksum. So, as a minimum, you will need to > > decompress the object data, calculate its adler32 checksum and write the > > zlib header yourself. > > Hmph. Thanks for helping, but it sounds like my original plan > was not useful at all. Probably inflating would be still > cheaper than inflating and then deflating, but it would not be > as cool as a straight copy. Sigh...
Actually you can calculate adler32 checksum of object data from adler32(header+data) (available at the end of the loose object file), adler32(header) (which you will need to calculate) and len(data) (which is available in the header):
#define ADLER32_BASE 65521UL
unsigned int adler32_split(unsigned int adler_full, unsigned int adler_1,
unsigned long len_2)
{
unsigned long s1_1 = adler_1 & 0xffff;
unsigned long s1_2 = (adler_1 >> 16) & 0xffff;
unsigned long rem = len_2 % ADLER32_BASE;
unsigned long s_1_offset = (s1_1 + ADLER32_BASE - 1) % ADLER32_BASE;
unsigned long s_2_offset = (s1_2 + s_1_offset*rem) % ADLER32_BASE;
unsigned long sf_1 = adler_full & 0xffff;
unsigned long sf_2 = (adler_full >> 16) & 0xffff;
unsigned long s2_1 = (sf_1 + ADLER32_BASE - s_1_offset) % ADLER32_BASE;
unsigned long s2_2 = (sf_2 + ADLER32_BASE - s_2_offset) % ADLER32_BASE;
return (s2_2 << 16) | s2_1;
}However, the resulting code probably won't be pretty...