Merge branch 'rs/allocate-cache-entry-individually'
* 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
This commit is contained in:
commit
ef87690b27
3
cache.h
3
cache.h
@ -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 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_size(len) flexible_size(ondisk_cache_entry,len)
|
||||||
#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len)
|
#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len)
|
||||||
|
|
||||||
@ -316,7 +316,6 @@ struct index_state {
|
|||||||
struct string_list *resolve_undo;
|
struct string_list *resolve_undo;
|
||||||
struct cache_tree *cache_tree;
|
struct cache_tree *cache_tree;
|
||||||
struct cache_time timestamp;
|
struct cache_time timestamp;
|
||||||
void *alloc;
|
|
||||||
unsigned name_hash_initialized : 1,
|
unsigned name_hash_initialized : 1,
|
||||||
initialized : 1;
|
initialized : 1;
|
||||||
struct hash_table name_hash;
|
struct hash_table name_hash;
|
||||||
|
93
read-cache.c
93
read-cache.c
@ -1224,10 +1224,35 @@ int read_index(struct index_state *istate)
|
|||||||
return read_index_from(istate, get_index_file());
|
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;
|
size_t len;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
/* On-disk flags are just 16 bits */
|
||||||
|
flags = ntohs(ondisk->flags);
|
||||||
|
len = flags & CE_NAMEMASK;
|
||||||
|
|
||||||
|
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);
|
||||||
|
flags |= extended_flags;
|
||||||
|
name = ondisk2->name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name = ondisk->name;
|
||||||
|
|
||||||
|
if (len == CE_NAMEMASK)
|
||||||
|
len = strlen(name);
|
||||||
|
|
||||||
|
ce = xmalloc(cache_entry_size(len));
|
||||||
|
|
||||||
ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
|
ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
|
||||||
ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
|
ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
|
||||||
@ -1239,48 +1264,13 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
|
|||||||
ce->ce_uid = ntohl(ondisk->uid);
|
ce->ce_uid = ntohl(ondisk->uid);
|
||||||
ce->ce_gid = ntohl(ondisk->gid);
|
ce->ce_gid = ntohl(ondisk->gid);
|
||||||
ce->ce_size = ntohl(ondisk->size);
|
ce->ce_size = ntohl(ondisk->size);
|
||||||
/* On-disk flags are just 16 bits */
|
ce->ce_flags = flags;
|
||||||
ce->ce_flags = ntohs(ondisk->flags);
|
|
||||||
|
|
||||||
hashcpy(ce->sha1, ondisk->sha1);
|
hashcpy(ce->sha1, ondisk->sha1);
|
||||||
|
|
||||||
len = ce->ce_flags & CE_NAMEMASK;
|
memcpy(ce->name, name, len);
|
||||||
|
ce->name[len] = '\0';
|
||||||
if (ce->ce_flags & CE_EXTENDED) {
|
return ce;
|
||||||
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;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remember to discard_cache() before reading a different cache! */
|
/* remember to discard_cache() before reading a different cache! */
|
||||||
@ -1288,7 +1278,7 @@ int read_index_from(struct index_state *istate, const char *path)
|
|||||||
{
|
{
|
||||||
int fd, i;
|
int fd, i;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
unsigned long src_offset, dst_offset;
|
unsigned long src_offset;
|
||||||
struct cache_header *hdr;
|
struct cache_header *hdr;
|
||||||
void *mmap;
|
void *mmap;
|
||||||
size_t mmap_size;
|
size_t mmap_size;
|
||||||
@ -1327,29 +1317,18 @@ int read_index_from(struct index_state *istate, const char *path)
|
|||||||
istate->cache_nr = ntohl(hdr->hdr_entries);
|
istate->cache_nr = ntohl(hdr->hdr_entries);
|
||||||
istate->cache_alloc = alloc_nr(istate->cache_nr);
|
istate->cache_alloc = alloc_nr(istate->cache_nr);
|
||||||
istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *));
|
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;
|
istate->initialized = 1;
|
||||||
|
|
||||||
src_offset = sizeof(*hdr);
|
src_offset = sizeof(*hdr);
|
||||||
dst_offset = 0;
|
|
||||||
for (i = 0; i < istate->cache_nr; i++) {
|
for (i = 0; i < istate->cache_nr; i++) {
|
||||||
struct ondisk_cache_entry *disk_ce;
|
struct ondisk_cache_entry *disk_ce;
|
||||||
struct cache_entry *ce;
|
struct cache_entry *ce;
|
||||||
|
|
||||||
disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
|
disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
|
||||||
ce = (struct cache_entry *)((char *)istate->alloc + dst_offset);
|
ce = create_from_disk(disk_ce);
|
||||||
convert_from_disk(disk_ce, ce);
|
|
||||||
set_index_entry(istate, i, ce);
|
set_index_entry(istate, i, ce);
|
||||||
|
|
||||||
src_offset += ondisk_ce_size(ce);
|
src_offset += ondisk_ce_size(ce);
|
||||||
dst_offset += ce_size(ce);
|
|
||||||
}
|
}
|
||||||
istate->timestamp.sec = st.st_mtime;
|
istate->timestamp.sec = st.st_mtime;
|
||||||
istate->timestamp.nsec = ST_MTIME_NSEC(st);
|
istate->timestamp.nsec = ST_MTIME_NSEC(st);
|
||||||
@ -1383,11 +1362,15 @@ unmap:
|
|||||||
|
|
||||||
int is_index_unborn(struct index_state *istate)
|
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 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);
|
resolve_undo_clear_index(istate);
|
||||||
istate->cache_nr = 0;
|
istate->cache_nr = 0;
|
||||||
istate->cache_changed = 0;
|
istate->cache_changed = 0;
|
||||||
@ -1396,8 +1379,6 @@ int discard_index(struct index_state *istate)
|
|||||||
istate->name_hash_initialized = 0;
|
istate->name_hash_initialized = 0;
|
||||||
free_hash(&istate->name_hash);
|
free_hash(&istate->name_hash);
|
||||||
cache_tree_free(&(istate->cache_tree));
|
cache_tree_free(&(istate->cache_tree));
|
||||||
free(istate->alloc);
|
|
||||||
istate->alloc = NULL;
|
|
||||||
istate->initialized = 0;
|
istate->initialized = 0;
|
||||||
|
|
||||||
/* no need to throw away allocated active_cache */
|
/* no need to throw away allocated active_cache */
|
||||||
|
Loading…
Reference in New Issue
Block a user