Make "struct tree" contain the pointer to the tree buffer
This allows us to avoid allocating information for names etc, because we can just use the information from the tree buffer directly. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
e0c97ca63d
commit
136f2e548a
@ -39,7 +39,7 @@ static struct tree_entry_list df_conflict_list = {
|
|||||||
|
|
||||||
typedef int (*merge_fn_t)(struct cache_entry **src);
|
typedef int (*merge_fn_t)(struct cache_entry **src);
|
||||||
|
|
||||||
static int entcmp(char *name1, int dir1, char *name2, int dir2)
|
static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
|
||||||
{
|
{
|
||||||
int len1 = strlen(name1);
|
int len1 = strlen(name1);
|
||||||
int len2 = strlen(name2);
|
int len2 = strlen(name2);
|
||||||
@ -67,7 +67,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
|
|||||||
int src_size = len + 1;
|
int src_size = len + 1;
|
||||||
do {
|
do {
|
||||||
int i;
|
int i;
|
||||||
char *first;
|
const char *first;
|
||||||
int firstdir = 0;
|
int firstdir = 0;
|
||||||
int pathlen;
|
int pathlen;
|
||||||
unsigned ce_size;
|
unsigned ce_size;
|
||||||
|
@ -136,10 +136,11 @@ static struct object_list **process_tree(struct tree *tree,
|
|||||||
p = process_tree(entry->item.tree, p, &me, entry->name);
|
p = process_tree(entry->item.tree, p, &me, entry->name);
|
||||||
else
|
else
|
||||||
p = process_blob(entry->item.blob, p, &me, entry->name);
|
p = process_blob(entry->item.blob, p, &me, entry->name);
|
||||||
free(entry->name);
|
|
||||||
free(entry);
|
free(entry);
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
|
free(tree->buffer);
|
||||||
|
tree->buffer = NULL;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,17 +198,16 @@ static int fsck_tree(struct tree *item)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(last->name);
|
|
||||||
free(last);
|
free(last);
|
||||||
}
|
}
|
||||||
|
|
||||||
last = entry;
|
last = entry;
|
||||||
}
|
}
|
||||||
if (last) {
|
if (last)
|
||||||
free(last->name);
|
|
||||||
free(last);
|
free(last);
|
||||||
}
|
|
||||||
item->entries = NULL;
|
item->entries = NULL;
|
||||||
|
free(item->buffer);
|
||||||
|
item->buffer = NULL;
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
if (has_full_path) {
|
if (has_full_path) {
|
||||||
|
5
object.c
5
object.c
@ -200,8 +200,11 @@ struct object *parse_object(const unsigned char *sha1)
|
|||||||
obj = &blob->object;
|
obj = &blob->object;
|
||||||
} else if (!strcmp(type, tree_type)) {
|
} else if (!strcmp(type, tree_type)) {
|
||||||
struct tree *tree = lookup_tree(sha1);
|
struct tree *tree = lookup_tree(sha1);
|
||||||
parse_tree_buffer(tree, buffer, size);
|
|
||||||
obj = &tree->object;
|
obj = &tree->object;
|
||||||
|
if (!tree->object.parsed) {
|
||||||
|
parse_tree_buffer(tree, buffer, size);
|
||||||
|
buffer = NULL;
|
||||||
|
}
|
||||||
} else if (!strcmp(type, commit_type)) {
|
} else if (!strcmp(type, commit_type)) {
|
||||||
struct commit *commit = lookup_commit(sha1);
|
struct commit *commit = lookup_commit(sha1);
|
||||||
parse_commit_buffer(commit, buffer, size);
|
parse_commit_buffer(commit, buffer, size);
|
||||||
|
47
tree.c
47
tree.c
@ -3,6 +3,7 @@
|
|||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
#include "tree-walk.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *tree_type = "tree";
|
const char *tree_type = "tree";
|
||||||
@ -145,46 +146,45 @@ struct tree *lookup_tree(const unsigned char *sha1)
|
|||||||
|
|
||||||
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
|
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
|
||||||
{
|
{
|
||||||
void *bufptr = buffer;
|
struct tree_desc desc;
|
||||||
struct tree_entry_list **list_p;
|
struct tree_entry_list **list_p;
|
||||||
int n_refs = 0;
|
int n_refs = 0;
|
||||||
|
|
||||||
if (item->object.parsed)
|
if (item->object.parsed)
|
||||||
return 0;
|
return 0;
|
||||||
item->object.parsed = 1;
|
item->object.parsed = 1;
|
||||||
|
item->buffer = buffer;
|
||||||
|
item->size = size;
|
||||||
|
|
||||||
|
desc.buf = buffer;
|
||||||
|
desc.size = size;
|
||||||
|
|
||||||
list_p = &item->entries;
|
list_p = &item->entries;
|
||||||
while (size) {
|
while (desc.size) {
|
||||||
struct object *obj;
|
unsigned mode;
|
||||||
|
const char *path;
|
||||||
|
const unsigned char *sha1;
|
||||||
struct tree_entry_list *entry;
|
struct tree_entry_list *entry;
|
||||||
int len = 1+strlen(bufptr);
|
|
||||||
unsigned char *file_sha1 = bufptr + len;
|
sha1 = tree_entry_extract(&desc, &path, &mode);
|
||||||
char *path = strchr(bufptr, ' ');
|
|
||||||
unsigned int mode;
|
|
||||||
if (size < len + 20 || !path ||
|
|
||||||
sscanf(bufptr, "%o", &mode) != 1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
entry = xmalloc(sizeof(struct tree_entry_list));
|
entry = xmalloc(sizeof(struct tree_entry_list));
|
||||||
entry->name = strdup(path + 1);
|
entry->name = path;
|
||||||
|
entry->mode = mode;
|
||||||
entry->directory = S_ISDIR(mode) != 0;
|
entry->directory = S_ISDIR(mode) != 0;
|
||||||
entry->executable = (mode & S_IXUSR) != 0;
|
entry->executable = (mode & S_IXUSR) != 0;
|
||||||
entry->symlink = S_ISLNK(mode) != 0;
|
entry->symlink = S_ISLNK(mode) != 0;
|
||||||
entry->zeropad = *(char *)bufptr == '0';
|
entry->zeropad = *(const char *)(desc.buf) == '0';
|
||||||
entry->mode = mode;
|
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
|
|
||||||
bufptr += len + 20;
|
update_tree_entry(&desc);
|
||||||
size -= len + 20;
|
|
||||||
|
|
||||||
if (entry->directory) {
|
if (entry->directory) {
|
||||||
entry->item.tree = lookup_tree(file_sha1);
|
entry->item.tree = lookup_tree(sha1);
|
||||||
obj = &entry->item.tree->object;
|
|
||||||
} else {
|
} else {
|
||||||
entry->item.blob = lookup_blob(file_sha1);
|
entry->item.blob = lookup_blob(sha1);
|
||||||
obj = &entry->item.blob->object;
|
|
||||||
}
|
}
|
||||||
if (obj)
|
n_refs++;
|
||||||
n_refs++;
|
|
||||||
*list_p = entry;
|
*list_p = entry;
|
||||||
list_p = &entry->next;
|
list_p = &entry->next;
|
||||||
}
|
}
|
||||||
@ -206,7 +206,6 @@ int parse_tree(struct tree *item)
|
|||||||
char type[20];
|
char type[20];
|
||||||
void *buffer;
|
void *buffer;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (item->object.parsed)
|
if (item->object.parsed)
|
||||||
return 0;
|
return 0;
|
||||||
@ -219,9 +218,7 @@ int parse_tree(struct tree *item)
|
|||||||
return error("Object %s not a tree",
|
return error("Object %s not a tree",
|
||||||
sha1_to_hex(item->object.sha1));
|
sha1_to_hex(item->object.sha1));
|
||||||
}
|
}
|
||||||
ret = parse_tree_buffer(item, buffer, size);
|
return parse_tree_buffer(item, buffer, size);
|
||||||
free(buffer);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tree *parse_tree_indirect(const unsigned char *sha1)
|
struct tree *parse_tree_indirect(const unsigned char *sha1)
|
||||||
|
4
tree.h
4
tree.h
@ -12,7 +12,7 @@ struct tree_entry_list {
|
|||||||
unsigned symlink : 1;
|
unsigned symlink : 1;
|
||||||
unsigned zeropad : 1;
|
unsigned zeropad : 1;
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
char *name;
|
const char *name;
|
||||||
union {
|
union {
|
||||||
struct object *any;
|
struct object *any;
|
||||||
struct tree *tree;
|
struct tree *tree;
|
||||||
@ -22,6 +22,8 @@ struct tree_entry_list {
|
|||||||
|
|
||||||
struct tree {
|
struct tree {
|
||||||
struct object object;
|
struct object object;
|
||||||
|
void *buffer;
|
||||||
|
unsigned long size;
|
||||||
struct tree_entry_list *entries;
|
struct tree_entry_list *entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user