Skip to content

Commit

Permalink
Merge branch 'rs/allocate-cache-entry-individually'
Browse files Browse the repository at this point in the history
* rs/allocate-cache-entry-individually:
  cache.h: put single NUL at end of struct cache_entry
  read-cache.c: allocate index entries individually

Conflicts:
	read-cache.c
  • Loading branch information
Junio C Hamano committed Dec 9, 2011
2 parents 51f737e + ee7825b commit ef87690
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 53 deletions.
3 changes: 1 addition & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ static inline unsigned int canon_mode(unsigned int mode)
}

#define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
#define cache_entry_size(len) flexible_size(cache_entry,len)
#define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1)
#define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len)
#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len)

Expand All @@ -316,7 +316,6 @@ struct index_state {
struct string_list *resolve_undo;
struct cache_tree *cache_tree;
struct cache_time timestamp;
void *alloc;
unsigned name_hash_initialized : 1,
initialized : 1;
struct hash_table name_hash;
Expand Down
83 changes: 32 additions & 51 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,71 +1224,61 @@ int read_index(struct index_state *istate)
return read_index_from(istate, get_index_file());
}

static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce)
static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk)
{
struct cache_entry *ce;
size_t len;
const char *name;
unsigned int flags;

ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
ce->ce_ctime.nsec = ntohl(ondisk->ctime.nsec);
ce->ce_mtime.nsec = ntohl(ondisk->mtime.nsec);
ce->ce_dev = ntohl(ondisk->dev);
ce->ce_ino = ntohl(ondisk->ino);
ce->ce_mode = ntohl(ondisk->mode);
ce->ce_uid = ntohl(ondisk->uid);
ce->ce_gid = ntohl(ondisk->gid);
ce->ce_size = ntohl(ondisk->size);
/* On-disk flags are just 16 bits */
ce->ce_flags = ntohs(ondisk->flags);

hashcpy(ce->sha1, ondisk->sha1);
flags = ntohs(ondisk->flags);
len = flags & CE_NAMEMASK;

len = ce->ce_flags & CE_NAMEMASK;

if (ce->ce_flags & CE_EXTENDED) {
if (flags & CE_EXTENDED) {
struct ondisk_cache_entry_extended *ondisk2;
int extended_flags;
ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
extended_flags = ntohs(ondisk2->flags2) << 16;
/* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
if (extended_flags & ~CE_EXTENDED_FLAGS)
die("Unknown index entry format %08x", extended_flags);
ce->ce_flags |= extended_flags;
flags |= extended_flags;
name = ondisk2->name;
}
else
name = ondisk->name;

if (len == CE_NAMEMASK)
len = strlen(name);
/*
* NEEDSWORK: If the original index is crafted, this copy could
* go unchecked.
*/
memcpy(ce->name, name, len + 1);
}

static inline size_t estimate_cache_size(size_t ondisk_size, unsigned int entries)
{
size_t fix_size_mem = offsetof(struct cache_entry, name);
size_t fix_size_dsk = offsetof(struct ondisk_cache_entry, name);
long per_entry = (fix_size_mem - fix_size_dsk + 7) & ~7;
ce = xmalloc(cache_entry_size(len));

/*
* Alignment can cause differences. This should be "alignof", but
* since that's a gcc'ism, just use the size of a pointer.
*/
per_entry += sizeof(void *);
return ondisk_size + entries*per_entry;
ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
ce->ce_ctime.nsec = ntohl(ondisk->ctime.nsec);
ce->ce_mtime.nsec = ntohl(ondisk->mtime.nsec);
ce->ce_dev = ntohl(ondisk->dev);
ce->ce_ino = ntohl(ondisk->ino);
ce->ce_mode = ntohl(ondisk->mode);
ce->ce_uid = ntohl(ondisk->uid);
ce->ce_gid = ntohl(ondisk->gid);
ce->ce_size = ntohl(ondisk->size);
ce->ce_flags = flags;

hashcpy(ce->sha1, ondisk->sha1);

memcpy(ce->name, name, len);
ce->name[len] = '\0';
return ce;
}

/* remember to discard_cache() before reading a different cache! */
int read_index_from(struct index_state *istate, const char *path)
{
int fd, i;
struct stat st;
unsigned long src_offset, dst_offset;
unsigned long src_offset;
struct cache_header *hdr;
void *mmap;
size_t mmap_size;
Expand Down Expand Up @@ -1327,29 +1317,18 @@ int read_index_from(struct index_state *istate, const char *path)
istate->cache_nr = ntohl(hdr->hdr_entries);
istate->cache_alloc = alloc_nr(istate->cache_nr);
istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *));

/*
* The disk format is actually larger than the in-memory format,
* due to space for nsec etc, so even though the in-memory one
* has room for a few more flags, we can allocate using the same
* index size
*/
istate->alloc = xmalloc(estimate_cache_size(mmap_size, istate->cache_nr));
istate->initialized = 1;

src_offset = sizeof(*hdr);
dst_offset = 0;
for (i = 0; i < istate->cache_nr; i++) {
struct ondisk_cache_entry *disk_ce;
struct cache_entry *ce;

disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
ce = (struct cache_entry *)((char *)istate->alloc + dst_offset);
convert_from_disk(disk_ce, ce);
ce = create_from_disk(disk_ce);
set_index_entry(istate, i, ce);

src_offset += ondisk_ce_size(ce);
dst_offset += ce_size(ce);
}
istate->timestamp.sec = st.st_mtime;
istate->timestamp.nsec = ST_MTIME_NSEC(st);
Expand Down Expand Up @@ -1383,11 +1362,15 @@ int read_index_from(struct index_state *istate, const char *path)

int is_index_unborn(struct index_state *istate)
{
return (!istate->cache_nr && !istate->alloc && !istate->timestamp.sec);
return (!istate->cache_nr && !istate->timestamp.sec);
}

int discard_index(struct index_state *istate)
{
int i;

for (i = 0; i < istate->cache_nr; i++)
free(istate->cache[i]);
resolve_undo_clear_index(istate);
istate->cache_nr = 0;
istate->cache_changed = 0;
Expand All @@ -1396,8 +1379,6 @@ int discard_index(struct index_state *istate)
istate->name_hash_initialized = 0;
free_hash(&istate->name_hash);
cache_tree_free(&(istate->cache_tree));
free(istate->alloc);
istate->alloc = NULL;
istate->initialized = 0;

/* no need to throw away allocated active_cache */
Expand Down

0 comments on commit ef87690

Please sign in to comment.