summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Blees <karsten.blees@gmail.com>2013-11-14 20:21:26 +0100
committerJunio C Hamano <gitster@pobox.com>2013-11-18 13:04:24 -0800
commit1c8cca190a1029d16450e61fbc4ce6f85a867f30 (patch)
treebc25e42ebb0485a955f368d9a561114eba203354
parente05881a4577cedca4d7456b3cb1f8bbd6f480df2 (diff)
downloadgit-1c8cca190a1029d16450e61fbc4ce6f85a867f30.tar.gz
name-hash.c: remove unreferenced directory entries
The new hashmap implementation supports remove, so remove and free directory entries that are no longer referenced by active cache entries. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--name-hash.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/name-hash.c b/name-hash.c
index c75fadf33b..effe96db0b 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -86,15 +86,16 @@ static void add_dir_entry(struct index_state *istate, struct cache_entry *ce)
static void remove_dir_entry(struct index_state *istate, struct cache_entry *ce)
{
/*
- * Release reference to the directory entry (and parents if 0).
- *
- * Note: we do not remove / free the entry because there's no
- * hash.[ch]::remove_hash and dir->next may point to other entries
- * that are still valid, so we must not free the memory.
+ * Release reference to the directory entry. If 0, remove and continue
+ * with parent directory.
*/
struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
- while (dir && dir->nr && !(--dir->nr))
- dir = dir->parent;
+ while (dir && !(--dir->nr)) {
+ struct dir_entry *parent = dir->parent;
+ hashmap_remove(&istate->dir_hash, dir, NULL);
+ free(dir);
+ dir = parent;
+ }
}
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)