Skip to content

Commit

Permalink
Replace use_packed_git with window cursors.
Browse files Browse the repository at this point in the history
Part of the implementation concept of the sliding mmap window for
pack access is to permit multiple windows per pack to be mapped
independently.  Since the inuse_cnt is associated with the mmap and
not with the file, this value is in struct pack_window and needs to
be incremented/decremented for each pack_window accessed by any code.

To faciliate that implementation we need to replace all uses of
use_packed_git() and unuse_packed_git() with a different API that
follows struct pack_window objects rather than struct packed_git.

The way this works is when we need to start accessing a pack for
the first time we should setup a new window 'cursor' by declaring
a local and setting it to NULL:

  struct pack_windows *w_curs = NULL;

To obtain the memory region which contains a specific section of
the pack file we invoke use_pack(), supplying the address of our
current window cursor:

  unsigned int len;
  unsigned char *addr = use_pack(p, &w_curs, offset, &len);

the returned address `addr` will be the first byte at `offset`
within the pack file.  The optional variable len will also be
updated with the number of bytes remaining following the address.

Multiple calls to use_pack() with the same window cursor will
update the window cursor, moving it from one window to another
when necessary.  In this way each window cursor variable maintains
only one struct pack_window inuse at a time.

Finally before exiting the scope which originally declared the window
cursor we must invoke unuse_pack() to unuse the current window (which
may be different from the one that was first obtained from use_pack):

  unuse_pack(&w_curs);

This implementation is still not complete with regards to multiple
windows, as only one window per pack file is supported right now.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Shawn O. Pearce authored and Junio C Hamano committed Dec 29, 2006
1 parent 9bc879c commit 03e79c8
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 67 deletions.
16 changes: 7 additions & 9 deletions builtin-pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ static unsigned long write_object(struct sha1file *f,
}
else {
struct packed_git *p = entry->in_pack;
struct pack_window *w_curs = NULL;

if (entry->delta) {
obj_type = (allow_ofs_delta && entry->delta->offset) ?
Expand All @@ -437,16 +438,14 @@ static unsigned long write_object(struct sha1file *f,
hdrlen += 20;
}

use_packed_git(p);
buf = p->windows->base
+ entry->in_pack_offset
+ entry->in_pack_header_size;
buf = use_pack(p, &w_curs, entry->in_pack_offset
+ entry->in_pack_header_size, NULL);
datalen = find_packed_object_size(p, entry->in_pack_offset)
- entry->in_pack_header_size;
if (!pack_to_stdout && check_inflate(buf, datalen, entry->size))
die("corrupt delta in pack %s", sha1_to_hex(entry->sha1));
sha1write(f, buf, datalen);
unuse_packed_git(p);
unuse_pack(&w_curs);
reused++;
}
if (entry->delta)
Expand Down Expand Up @@ -937,14 +936,13 @@ static void check_object(struct object_entry *entry)

if (entry->in_pack && !entry->preferred_base) {
struct packed_git *p = entry->in_pack;
struct pack_window *w_curs = NULL;
unsigned long left = p->pack_size - entry->in_pack_offset;
unsigned long size, used;
unsigned char *buf;
struct object_entry *base_entry = NULL;

use_packed_git(p);
buf = p->windows->base;
buf += entry->in_pack_offset;
buf = use_pack(p, &w_curs, entry->in_pack_offset, NULL);

/* We want in_pack_type even if we do not reuse delta.
* There is no point not reusing non-delta representations.
Expand Down Expand Up @@ -990,7 +988,7 @@ static void check_object(struct object_entry *entry)
if (base_name)
base_entry = locate_object_entry(base_name);
}
unuse_packed_git(p);
unuse_pack(&w_curs);
entry->in_pack_header_size = used;

if (base_entry) {
Expand Down
4 changes: 2 additions & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ extern void install_packed_git(struct packed_git *pack);
extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
struct packed_git *packs);

extern int use_packed_git(struct packed_git *);
extern void unuse_packed_git(struct packed_git *);
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, unsigned long, unsigned int *);
extern void unuse_pack(struct pack_window **);
extern struct packed_git *add_packed_git(char *, int, int);
extern int num_packed_objects(const struct packed_git *p);
extern int nth_packed_object_sha1(const struct packed_git *, int, unsigned char*);
Expand Down
22 changes: 12 additions & 10 deletions pack-check.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include "cache.h"
#include "pack.h"

static int verify_packfile(struct packed_git *p)
static int verify_packfile(struct packed_git *p,
struct pack_window **w_curs)
{
unsigned long index_size = p->index_size;
void *index_base = p->index_base;
Expand All @@ -13,7 +14,7 @@ static int verify_packfile(struct packed_git *p)
int nr_objects, err, i;

/* Header consistency check */
pack_base = p->windows->base;
pack_base = use_pack(p, w_curs, 0, NULL);
hdr = (struct pack_header*)pack_base;
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
return error("Packfile %s signature mismatch", p->pack_name);
Expand Down Expand Up @@ -72,13 +73,14 @@ static int verify_packfile(struct packed_git *p)

#define MAX_CHAIN 40

static void show_pack_info(struct packed_git *p)
static void show_pack_info(struct packed_git *p,
struct pack_window **w_curs)
{
struct pack_header *hdr;
int nr_objects, i;
unsigned int chain_histogram[MAX_CHAIN];

hdr = (struct pack_header*)p->windows->base;
hdr = (struct pack_header*)use_pack(p, w_curs, 0, NULL);
nr_objects = ntohl(hdr->hdr_entries);
memset(chain_histogram, 0, sizeof(chain_histogram));

Expand Down Expand Up @@ -142,18 +144,18 @@ int verify_pack(struct packed_git *p, int verbose)

if (!ret) {
/* Verify pack file */
use_packed_git(p);
ret = verify_packfile(p);
unuse_packed_git(p);
struct pack_window *w_curs = NULL;
ret = verify_packfile(p, &w_curs);
unuse_pack(&w_curs);
}

if (verbose) {
if (ret)
printf("%s: bad\n", p->pack_name);
else {
use_packed_git(p);
show_pack_info(p);
unuse_packed_git(p);
struct pack_window *w_curs = NULL;
show_pack_info(p, &w_curs);
unuse_pack(&w_curs);
printf("%s: ok\n", p->pack_name);
}
}
Expand Down
Loading

0 comments on commit 03e79c8

Please sign in to comment.