v2 removes unrelated changes and the dummy_entry. strip_len is also replaced with copy_len to reduce repeated subtraction calculation. Diff: diff --git a/read-cache.c b/read-cache.c index 5c04c8f200..8628d0f3a8 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1713,7 +1713,7 @@ int read_index(struct index_state *istate) return read_index_from(istate, get_index_file(), get_git_dir()); } -static struct cache_entry *create_from_disk(struct mem_pool *mem_pool, +static struct cache_entry *create_from_disk(struct index_state *istate, struct ondisk_cache_entry *ondisk, unsigned long *ent_size, const struct cache_entry *previous_ce) @@ -1722,7 +1722,15 @@ static struct cache_entry *create_from_disk(struct mem_pool *mem_pool, size_t len; const char *name; unsigned int flags; - size_t strip_len; + size_t copy_len; + /* + * Adjacent cache entries tend to share the leading paths, so it makes + * sense to only store the differences in later entries. In the v4 + * on-disk format of the index, each on-disk cache entry stores the + * number of bytes to be stripped from the end of the previous name, + * and the bytes to append to the result, to come up with its name. + */ + int expand_name_field = istate->version == 4; /* On-disk flags are just 16 bits */ flags = get_be16(&ondisk->flags); @@ -1735,37 +1743,37 @@ static struct cache_entry *create_from_disk(struct mem_pool *mem_pool, extended_flags = get_be16(&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); + die("Unknown index entry format %08x", extended_flags); flags |= extended_flags; name = ondisk2->name; } else name = ondisk->name; - /* - * Adjacent cache entries tend to share the leading paths, so it makes - * sense to only store the differences in later entries. In the v4 - * on-disk format of the index, each on-disk cache entry stores the - * number of bytes to be stripped from the end of the previous name, - * and the bytes to append to the result, to come up with its name. - */ - if (previous_ce) { + if (expand_name_field) { const unsigned char *cp = (const unsigned char *)name; + size_t strip_len, previous_len; + previous_len = previous_ce ? previous_ce->ce_namelen : 0; strip_len = decode_varint(&cp); - if (previous_ce->ce_namelen < strip_len) - die(_("malformed name field in the index, path '%s'"), - previous_ce->name); + if (previous_len < strip_len) { + if (previous_ce) + die(_("malformed name field in the index, near path '%s'"), + previous_ce->name); + else + die(_("malformed name field in the index in the first path")); + } + copy_len = previous_len - strip_len; name = (const char *)cp; } if (len == CE_NAMEMASK) { len = strlen(name); - if (previous_ce) - len += previous_ce->ce_namelen - strip_len; + if (expand_name_field) + len += copy_len; } - ce = mem_pool__ce_alloc(mem_pool, len); + ce = mem_pool__ce_alloc(istate->ce_mem_pool, len); ce->ce_stat_data.sd_ctime.sec = get_be32(&ondisk->ctime.sec); ce->ce_stat_data.sd_mtime.sec = get_be32(&ondisk->mtime.sec); @@ -1782,9 +1790,9 @@ static struct cache_entry *create_from_disk(struct mem_pool *mem_pool, ce->index = 0; hashcpy(ce->oid.hash, ondisk->sha1); - if (previous_ce) { - size_t copy_len = previous_ce->ce_namelen - strip_len; - memcpy(ce->name, previous_ce->name, copy_len); + if (expand_name_field) { + if (copy_len) + memcpy(ce->name, previous_ce->name, copy_len); memcpy(ce->name + copy_len, name, len + 1 - copy_len); *ent_size = (name - ((char *)ondisk)) + len + 1 - copy_len; } else { @@ -1885,7 +1893,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) void *mmap; size_t mmap_size; const struct cache_entry *previous_ce = NULL; - struct cache_entry *dummy_entry = NULL; if (istate->initialized) return istate->cache_nr; @@ -1923,7 +1930,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) istate->initialized = 1; if (istate->version == 4) { - previous_ce = dummy_entry = make_empty_transient_cache_entry(0); mem_pool_init(&istate->ce_mem_pool, estimate_cache_size_from_compressed(istate->cache_nr)); } else { @@ -1938,14 +1944,12 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) unsigned long consumed; disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset); - ce = create_from_disk(istate->ce_mem_pool, disk_ce, &consumed, previous_ce); + ce = create_from_disk(istate, disk_ce, &consumed, previous_ce); set_index_entry(istate, i, ce); src_offset += consumed; - if (previous_ce) - previous_ce = ce; + previous_ce = ce; } - free(dummy_entry); istate->timestamp.sec = st.st_mtime; istate->timestamp.nsec = ST_MTIME_NSEC(st); Nguyễn Thái Ngọc Duy (1): read-cache.c: optimize reading index format v4 read-cache.c | 128 ++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 68 deletions(-) -- 2.19.0.rc0.337.ge906d732e7