-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove "refs" field from "struct object"
This shrinks "struct object" to the absolutely minimal size possible. It now contains /only/ the object flags and the SHA1 hash name of the object. The "refs" field, which is really needed only for fsck, is maintained in a separate hashed lookup-table, allowing all normal users to totally ignore it. This helps memory usage, although not as much as I hoped: it looks like the allocation overhead of malloc (and the alignment constraints in particular) means that while the structure size shrinks, the actual allocation overhead mostly does not. [ That said: memory usage is actually down, but not as much as it should be: I suspect just one of the object types actually ended up shrinking its effective allocation size. To get to the next level, we probably need specialized allocators that don't pad the allocation more than necessary. ] The separation makes for some code cleanup, though, and makes the ref tracking that fsck wants a clearly separate thing. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
- Loading branch information
Linus Torvalds
authored and
Junio C Hamano
committed
Jun 18, 2006
1 parent
9cd625b
commit 3e4339e
Showing
5 changed files
with
149 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#include "cache.h" | ||
#include "object.h" | ||
|
||
int track_object_refs = 0; | ||
|
||
static unsigned int refs_hash_size, nr_object_refs; | ||
static struct object_refs **refs_hash; | ||
|
||
static unsigned int hash_obj(struct object *obj, unsigned int n) | ||
{ | ||
unsigned int hash = *(unsigned int *)obj->sha1; | ||
return hash % n; | ||
} | ||
|
||
static void grow_refs_hash(void) | ||
{ | ||
int i; | ||
int new_hash_size = (refs_hash_size + 1000) * 3 / 2; | ||
struct object_refs **new_hash; | ||
|
||
new_hash = calloc(new_hash_size, sizeof(struct object_refs *)); | ||
for (i = 0; i < refs_hash_size; i++) { | ||
int j; | ||
struct object_refs *ref = refs_hash[i]; | ||
if (!ref) | ||
continue; | ||
j = hash_obj(ref->base, new_hash_size); | ||
new_hash[j] = ref; | ||
} | ||
free(refs_hash); | ||
refs_hash = new_hash; | ||
refs_hash_size = new_hash_size; | ||
} | ||
|
||
static void insert_ref_hash(struct object_refs *ref) | ||
{ | ||
int j = hash_obj(ref->base, refs_hash_size); | ||
|
||
while (refs_hash[j]) { | ||
j++; | ||
if (j >= refs_hash_size) | ||
j = 0; | ||
} | ||
refs_hash[j] = ref; | ||
} | ||
|
||
static void add_object_refs(struct object *obj, struct object_refs *ref) | ||
{ | ||
int nr = nr_object_refs + 1; | ||
|
||
if (nr > refs_hash_size * 2 / 3) | ||
grow_refs_hash(); | ||
ref->base = obj; | ||
insert_ref_hash(ref); | ||
nr_object_refs = nr; | ||
} | ||
|
||
struct object_refs *lookup_object_refs(struct object *obj) | ||
{ | ||
int j = hash_obj(obj, refs_hash_size); | ||
struct object_refs *ref; | ||
|
||
while ((ref = refs_hash[j]) != NULL) { | ||
if (ref->base == obj) | ||
break; | ||
j++; | ||
if (j >= refs_hash_size) | ||
j = 0; | ||
} | ||
return ref; | ||
} | ||
|
||
struct object_refs *alloc_object_refs(unsigned count) | ||
{ | ||
struct object_refs *refs; | ||
size_t size = sizeof(*refs) + count*sizeof(struct object *); | ||
|
||
refs = xcalloc(1, size); | ||
refs->count = count; | ||
return refs; | ||
} | ||
|
||
static int compare_object_pointers(const void *a, const void *b) | ||
{ | ||
const struct object * const *pa = a; | ||
const struct object * const *pb = b; | ||
if (*pa == *pb) | ||
return 0; | ||
else if (*pa < *pb) | ||
return -1; | ||
else | ||
return 1; | ||
} | ||
|
||
void set_object_refs(struct object *obj, struct object_refs *refs) | ||
{ | ||
unsigned int i, j; | ||
|
||
/* Do not install empty list of references */ | ||
if (refs->count < 1) { | ||
free(refs); | ||
return; | ||
} | ||
|
||
/* Sort the list and filter out duplicates */ | ||
qsort(refs->ref, refs->count, sizeof(refs->ref[0]), | ||
compare_object_pointers); | ||
for (i = j = 1; i < refs->count; i++) { | ||
if (refs->ref[i] != refs->ref[i - 1]) | ||
refs->ref[j++] = refs->ref[i]; | ||
} | ||
if (j < refs->count) { | ||
/* Duplicates were found - reallocate list */ | ||
size_t size = sizeof(*refs) + j*sizeof(struct object *); | ||
refs->count = j; | ||
refs = xrealloc(refs, size); | ||
} | ||
|
||
for (i = 0; i < refs->count; i++) | ||
refs->ref[i]->used = 1; | ||
add_object_refs(obj, refs); | ||
} | ||
|
||
void mark_reachable(struct object *obj, unsigned int mask) | ||
{ | ||
const struct object_refs *refs; | ||
|
||
if (!track_object_refs) | ||
die("cannot do reachability with object refs turned off"); | ||
/* If we've been here already, don't bother */ | ||
if (obj->flags & mask) | ||
return; | ||
obj->flags |= mask; | ||
refs = lookup_object_refs(obj); | ||
if (refs) { | ||
unsigned i; | ||
for (i = 0; i < refs->count; i++) | ||
mark_reachable(refs->ref[i], mask); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters