Strip namelen out of ce_flags into a ce_namelen field

Strip the name length from the ce_flags field and move it into its own ce_namelen field in struct cache_entry. This will both give us a tiny bit of a performance enhancement when working with long pathnames and is a refactoring for more readability of the code. It enhances readability, by making it more clear what is a flag, and where the length is stored and make it clear which functions use stages in comparisions and which only use the length. It also makes CE_NAMEMASK private, so that users don't mistakenly write the name length in the flags. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Gummerer committed Jul 11, 2012 at 11:22 UTC b60e188c51242b72061b5f2f0d4df80397f6125a
8 files changed +63 -51
builtin/apply.c
+2 -1
@@ -3510,7 +3510,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
3510 ce = xcalloc(1, ce_size);
3511 memcpy(ce->name, path, namelen);
3512 ce->ce_mode = create_ce_mode(mode);
3513 - ce->ce_flags = namelen;
3513 + ce->ce_flags = create_ce_flags(0);
3514 + ce->ce_namelen = namelen;
3515 if (S_ISGITLINK(mode)) {
3516 const char *s = buf;
3517
builtin/blame.c
+2 -1
@@ -2171,7 +2171,8 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
2171 ce = xcalloc(1, size);
2172 hashcpy(ce->sha1, origin->blob_sha1);
2173 memcpy(ce->name, path, len);
2174 - ce->ce_flags = create_ce_flags(len, 0);
2174 + ce->ce_flags = create_ce_flags(0);
2175 + ce->ce_namelen = len;
2176 ce->ce_mode = create_ce_mode(mode);
2177 add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
2178
builtin/checkout.c
+2 -1
@@ -73,7 +73,8 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
73 hashcpy(ce->sha1, sha1);
74 memcpy(ce->name, base, baselen);
75 memcpy(ce->name + baselen, pathname, len - baselen);
76 - ce->ce_flags = create_ce_flags(len, 0) | CE_UPDATE;
76 + ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
77 + ce->ce_namelen = len;
78 ce->ce_mode = create_ce_mode(mode);
79 add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
80 return 0;
builtin/update-index.c
+6 -3
@@ -95,7 +95,8 @@ static int add_one_path(struct cache_entry *old, const char *path, int len, stru
95 size = cache_entry_size(len);
96 ce = xcalloc(1, size);
97 memcpy(ce->name, path, len);
98 - ce->ce_flags = len;
98 + ce->ce_flags = create_ce_flags(0);
99 + ce->ce_namelen = len;
100 fill_stat_cache_info(ce, st);
101 ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
102
@@ -229,7 +230,8 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
230
231 hashcpy(ce->sha1, sha1);
232 memcpy(ce->name, path, len);
232 - ce->ce_flags = create_ce_flags(len, stage);
233 + ce->ce_flags = create_ce_flags(stage);
234 + ce->ce_namelen = len;
235 ce->ce_mode = create_ce_mode(mode);
236 if (assume_unchanged)
237 ce->ce_flags |= CE_VALID;
@@ -427,7 +429,8 @@ static struct cache_entry *read_one_ent(const char *which,
429
430 hashcpy(ce->sha1, sha1);
431 memcpy(ce->name, path, namelen);
430 - ce->ce_flags = create_ce_flags(namelen, stage);
432 + ce->ce_flags = create_ce_flags(stage);
433 + ce->ce_namelen = namelen;
434 ce->ce_mode = create_ce_mode(mode);
435 return ce;
436 }
cache.h
+6 -13
@@ -128,13 +128,13 @@ struct cache_entry {
128 unsigned int ce_gid;
129 unsigned int ce_size;
130 unsigned int ce_flags;
131 + unsigned int ce_namelen;
132 unsigned char sha1[20];
133 struct cache_entry *next;
134 struct cache_entry *dir_next;
135 char name[FLEX_ARRAY]; /* more */
136 };
137
137 -#define CE_NAMEMASK (0x0fff)
138 #define CE_STAGEMASK (0x3000)
139 #define CE_EXTENDED (0x4000)
140 #define CE_VALID (0x8000)
@@ -198,21 +198,12 @@ static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry
198 dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
199 }
200
201 -static inline unsigned create_ce_flags(size_t len, unsigned stage)
201 +static inline unsigned create_ce_flags(unsigned stage)
202 {
203 - if (len >= CE_NAMEMASK)
204 - len = CE_NAMEMASK;
205 - return (len | (stage << CE_STAGESHIFT));
206 -}
207 -
208 -static inline size_t ce_namelen(const struct cache_entry *ce)
209 -{
210 - size_t len = ce->ce_flags & CE_NAMEMASK;
211 - if (len < CE_NAMEMASK)
212 - return len;
213 - return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK;
203 + return (stage << CE_STAGESHIFT);
204 }
205
206 +#define ce_namelen(ce) ((ce)->ce_namelen)
207 #define ce_size(ce) cache_entry_size(ce_namelen(ce))
208 #define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
209 #define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
@@ -451,6 +442,7 @@ extern int discard_index(struct index_state *);
442 extern int unmerged_index(const struct index_state *);
443 extern int verify_path(const char *path);
444 extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
445 +extern int index_name_stage_pos(const struct index_state *, const char *name, int namelen, int stage);
446 extern int index_name_pos(const struct index_state *, const char *name, int namelen);
447 #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
448 #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
@@ -863,6 +855,7 @@ extern int validate_headref(const char *ref);
855 extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
856 extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
857 extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
858 +extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2);
859
860 extern void *read_object_with_reference(const unsigned char *sha1,
861 const char *required_type,
read-cache.c
+39 -28
@@ -17,6 +17,10 @@
17
18 static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
19
20 +/* Mask for the name length in ce_flags in the on-disk index */
21 +
22 +#define CE_NAMEMASK (0x0fff)
23 +
24 /* Index extensions.
25 *
26 * The first letter should be 'A'..'Z' for extensions that are not
@@ -54,8 +58,8 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
58
59 new = xmalloc(cache_entry_size(namelen));
60 copy_cache_entry(new, old);
57 - new->ce_flags &= ~(CE_STATE_MASK | CE_NAMEMASK);
58 - new->ce_flags |= (namelen >= CE_NAMEMASK ? CE_NAMEMASK : namelen);
61 + new->ce_flags &= ~CE_STATE_MASK;
62 + new->ce_namelen = namelen;
63 memcpy(new->name, new_name, namelen + 1);
64
65 cache_tree_invalidate_path(istate->cache_tree, old->name);
@@ -395,17 +399,10 @@ int df_name_compare(const char *name1, int len1, int mode1,
399 return c1 - c2;
400 }
401
398 -int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
402 +int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2)
403 {
400 - int len1, len2, len, cmp;
401 -
402 - len1 = flags1 & CE_NAMEMASK;
403 - if (CE_NAMEMASK <= len1)
404 - len1 = strlen(name1 + CE_NAMEMASK) + CE_NAMEMASK;
405 - len2 = flags2 & CE_NAMEMASK;
406 - if (CE_NAMEMASK <= len2)
407 - len2 = strlen(name2 + CE_NAMEMASK) + CE_NAMEMASK;
408 - len = len1 < len2 ? len1 : len2;
404 + int len = len1 < len2 ? len1 : len2;
405 + int cmp;
406
407 cmp = memcmp(name1, name2, len);
408 if (cmp)
@@ -415,18 +412,19 @@ int cache_name_compare(const char *name1, int flags1, const char *name2, int fla
412 if (len1 > len2)
413 return 1;
414
418 - /* Compare stages */
419 - flags1 &= CE_STAGEMASK;
420 - flags2 &= CE_STAGEMASK;
421 -
422 - if (flags1 < flags2)
415 + if (stage1 < stage2)
416 return -1;
424 - if (flags1 > flags2)
417 + if (stage1 > stage2)
418 return 1;
419 return 0;
420 }
421
429 -int index_name_pos(const struct index_state *istate, const char *name, int namelen)
422 +int cache_name_compare(const char *name1, int len1, const char *name2, int len2)
423 +{
424 + return cache_name_stage_compare(name1, len1, 0, name2, len2, 0);
425 +}
426 +
427 +int index_name_stage_pos(const struct index_state *istate, const char *name, int namelen, int stage)
428 {
429 int first, last;
430
@@ -435,7 +433,7 @@ int index_name_pos(const struct index_state *istate, const char *name, int namel
433 while (last > first) {
434 int next = (last + first) >> 1;
435 struct cache_entry *ce = istate->cache[next];
438 - int cmp = cache_name_compare(name, namelen, ce->name, ce->ce_flags);
436 + int cmp = cache_name_stage_compare(name, namelen, stage, ce->name, ce_namelen(ce), ce_stage(ce));
437 if (!cmp)
438 return next;
439 if (cmp < 0) {
@@ -447,6 +445,11 @@ int index_name_pos(const struct index_state *istate, const char *name, int namel
445 return -first-1;
446 }
447
448 +int index_name_pos(const struct index_state *istate, const char *name, int namelen)
449 +{
450 + return index_name_stage_pos(istate, name, namelen, 0);
451 +}
452 +
453 /* Remove entry, return true if there are more entries to go.. */
454 int remove_index_entry_at(struct index_state *istate, int pos)
455 {
@@ -586,7 +589,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
589 size = cache_entry_size(namelen);
590 ce = xcalloc(1, size);
591 memcpy(ce->name, path, namelen);
589 - ce->ce_flags = namelen;
592 + ce->ce_namelen = namelen;
593 if (!intent_only)
594 fill_stat_cache_info(ce, st);
595 else
@@ -688,7 +691,8 @@ struct cache_entry *make_cache_entry(unsigned int mode,
691
692 hashcpy(ce->sha1, sha1);
693 memcpy(ce->name, path, len);
691 - ce->ce_flags = create_ce_flags(len, stage);
694 + ce->ce_flags = create_ce_flags(stage);
695 + ce->ce_namelen = len;
696 ce->ce_mode = create_ce_mode(mode);
697
698 if (refresh)
@@ -825,7 +829,7 @@ static int has_dir_name(struct index_state *istate,
829 }
830 len = slash - name;
831
828 - pos = index_name_pos(istate, name, create_ce_flags(len, stage));
832 + pos = index_name_stage_pos(istate, name, len, stage);
833 if (pos >= 0) {
834 /*
835 * Found one, but not so fast. This could
@@ -915,7 +919,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
919 int new_only = option & ADD_CACHE_NEW_ONLY;
920
921 cache_tree_invalidate_path(istate->cache_tree, ce->name);
918 - pos = index_name_pos(istate, ce->name, ce->ce_flags);
922 + pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce));
923
924 /* existing match? Just replace it. */
925 if (pos >= 0) {
@@ -947,7 +951,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
951 if (!ok_to_replace)
952 return error("'%s' appears as both a file and as a directory",
953 ce->name);
950 - pos = index_name_pos(istate, ce->name, ce->ce_flags);
954 + pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce));
955 pos = -pos-1;
956 }
957 return pos + 1;
@@ -1324,7 +1328,8 @@ static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *on
1328 ce->ce_uid = ntoh_l(ondisk->uid);
1329 ce->ce_gid = ntoh_l(ondisk->gid);
1330 ce->ce_size = ntoh_l(ondisk->size);
1327 - ce->ce_flags = flags;
1331 + ce->ce_flags = flags & ~CE_NAMEMASK;
1332 + ce->ce_namelen = len;
1333 hashcpy(ce->sha1, ondisk->sha1);
1334 memcpy(ce->name, name, len);
1335 ce->name[len] = '\0';
@@ -1651,6 +1656,8 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
1656 static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
1657 struct cache_entry *ce)
1658 {
1659 + short flags;
1660 +
1661 ondisk->ctime.sec = htonl(ce->ce_ctime.sec);
1662 ondisk->mtime.sec = htonl(ce->ce_mtime.sec);
1663 ondisk->ctime.nsec = htonl(ce->ce_ctime.nsec);
@@ -1662,7 +1669,10 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
1669 ondisk->gid = htonl(ce->ce_gid);
1670 ondisk->size = htonl(ce->ce_size);
1671 hashcpy(ondisk->sha1, ce->sha1);
1665 - ondisk->flags = htons(ce->ce_flags);
1672 +
1673 + flags = ce->ce_flags;
1674 + flags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));
1675 + ondisk->flags = htons(flags);
1676 if (ce->ce_flags & CE_EXTENDED) {
1677 struct ondisk_cache_entry_extended *ondisk2;
1678 ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
@@ -1850,7 +1860,8 @@ int read_index_unmerged(struct index_state *istate)
1860 size = cache_entry_size(len);
1861 new_ce = xcalloc(1, size);
1862 memcpy(new_ce->name, ce->name, len);
1853 - new_ce->ce_flags = create_ce_flags(len, 0) | CE_CONFLICTED;
1863 + new_ce->ce_flags = create_ce_flags(0) | CE_CONFLICTED;
1864 + new_ce->ce_namelen = len;
1865 new_ce->ce_mode = ce->ce_mode;
1866 if (add_index_entry(istate, new_ce, 0))
1867 return error("%s: cannot drop to stage #0",
tree.c
+4 -3
@@ -22,7 +22,8 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b
22 ce = xcalloc(1, size);
23
24 ce->ce_mode = create_ce_mode(mode);
25 - ce->ce_flags = create_ce_flags(baselen + len, stage);
25 + ce->ce_flags = create_ce_flags(stage);
26 + ce->ce_namelen = baselen + len;
27 memcpy(ce->name, base, baselen);
28 memcpy(ce->name + baselen, pathname, len+1);
29 hashcpy(ce->sha1, sha1);
@@ -133,8 +134,8 @@ static int cmp_cache_name_compare(const void *a_, const void *b_)
134
135 ce1 = *((const struct cache_entry **)a_);
136 ce2 = *((const struct cache_entry **)b_);
136 - return cache_name_compare(ce1->name, ce1->ce_flags,
137 - ce2->name, ce2->ce_flags);
137 + return cache_name_stage_compare(ce1->name, ce1->ce_namelen, ce_stage(ce1),
138 + ce2->name, ce2->ce_namelen, ce_stage(ce2));
139 }
140
141 int read_tree(struct tree *tree, int stage, struct pathspec *match)
unpack-trees.c
+2 -1
@@ -539,7 +539,8 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con
539 struct cache_entry *ce = xcalloc(1, cache_entry_size(len));
540
541 ce->ce_mode = create_ce_mode(n->mode);
542 - ce->ce_flags = create_ce_flags(len, stage);
542 + ce->ce_flags = create_ce_flags(stage);
543 + ce->ce_namelen = len;
544 hashcpy(ce->sha1, n->sha1);
545 make_traverse_path(ce->name, info, n);
546