mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 18:38:58 +00:00
Merge pull request #3759 from libgit2/cmn/faster-header
odb: avoid inflating the full delta to read the header
This commit is contained in:
commit
4d384d6bbe
@ -49,6 +49,37 @@ int git__delta_read_header(
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DELTA_HEADER_BUFFER_LEN 16
|
||||
int git__delta_read_header_fromstream(size_t *base_sz, size_t *res_sz, git_packfile_stream *stream)
|
||||
{
|
||||
static const size_t buffer_len = DELTA_HEADER_BUFFER_LEN;
|
||||
unsigned char buffer[DELTA_HEADER_BUFFER_LEN];
|
||||
const unsigned char *delta, *delta_end;
|
||||
size_t len;
|
||||
ssize_t read;
|
||||
|
||||
len = read = 0;
|
||||
while (len < buffer_len) {
|
||||
read = git_packfile_stream_read(stream, &buffer[len], buffer_len - len);
|
||||
|
||||
if (read == 0)
|
||||
break;
|
||||
|
||||
if (read == GIT_EBUFS)
|
||||
continue;
|
||||
|
||||
len += read;
|
||||
}
|
||||
|
||||
delta = buffer;
|
||||
delta_end = delta + len;
|
||||
if ((hdr_sz(base_sz, &delta, delta_end) < 0) ||
|
||||
(hdr_sz(res_sz, &delta, delta_end) < 0))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git__delta_apply(
|
||||
git_rawobj *out,
|
||||
const unsigned char *base,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define INCLUDE_delta_apply_h__
|
||||
|
||||
#include "odb.h"
|
||||
#include "pack.h"
|
||||
|
||||
/**
|
||||
* Apply a git binary delta to recover the original content.
|
||||
@ -47,4 +48,15 @@ extern int git__delta_read_header(
|
||||
size_t *base_sz,
|
||||
size_t *res_sz);
|
||||
|
||||
/**
|
||||
* Read the header of a git binary delta
|
||||
*
|
||||
* This variant reads just enough from the packfile stream to read the
|
||||
* delta header.
|
||||
*/
|
||||
extern int git__delta_read_header_fromstream(
|
||||
size_t *base_sz,
|
||||
size_t *res_sz,
|
||||
git_packfile_stream *stream);
|
||||
|
||||
#endif
|
||||
|
11
src/pack.c
11
src/pack.c
@ -499,15 +499,14 @@ int git_packfile_resolve_header(
|
||||
|
||||
if (type == GIT_OBJ_OFS_DELTA || type == GIT_OBJ_REF_DELTA) {
|
||||
size_t base_size;
|
||||
git_rawobj delta;
|
||||
git_packfile_stream stream;
|
||||
|
||||
base_offset = get_delta_base(p, &w_curs, &curpos, type, offset);
|
||||
git_mwindow_close(&w_curs);
|
||||
error = packfile_unpack_compressed(&delta, p, &w_curs, &curpos, size, type);
|
||||
git_mwindow_close(&w_curs);
|
||||
if (error < 0)
|
||||
if ((error = git_packfile_stream_open(&stream, p, curpos)) < 0)
|
||||
return error;
|
||||
error = git__delta_read_header(delta.data, delta.len, &base_size, size_p);
|
||||
git__free(delta.data);
|
||||
error = git__delta_read_header_fromstream(&base_size, size_p, &stream);
|
||||
git_packfile_stream_free(&stream);
|
||||
if (error < 0)
|
||||
return error;
|
||||
} else
|
||||
|
Loading…
Reference in New Issue
Block a user