dir.c: provide clear_directory() for reclaiming dir_struct memory
authorAdam Spiers <git@adamspiers.org>
Sun, 6 Jan 2013 16:58:05 +0000 (16:58 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 6 Jan 2013 22:26:37 +0000 (14:26 -0800)
By the end of a directory traversal, a dir_struct instance will
typically contains pointers to various data structures on the heap.
clear_directory() provides a convenient way to reclaim that memory.

Signed-off-by: Adam Spiers <git@adamspiers.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-directory-listing.txt
dir.c
dir.h

index fa9c8ae4618e9eb5c44ddc3f15443e10aa6bdd3e..fbceb629ab3c81b9cc42c0aaee4b2c866466c07c 100644 (file)
@@ -81,4 +81,6 @@ marked. If you to exclude files, make sure you have loaded index first.
 
 * Use `dir.entries[]`.
 
+* Call `free_directory()` when none of the contained elements are no longer in use.
+
 (JC)
diff --git a/dir.c b/dir.c
index d3f462bd155db75be078681dfa9168bdcb8c5d16..46f362ed69223f3c7429aaaaf08314e032b2e31d 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1557,3 +1557,33 @@ void free_pathspec(struct pathspec *pathspec)
        free(pathspec->items);
        pathspec->items = NULL;
 }
+
+/*
+ * Frees memory within dir which was allocated for exclude lists and
+ * the exclude_stack.  Does not free dir itself.
+ */
+void clear_directory(struct dir_struct *dir)
+{
+       int i, j;
+       struct exclude_list_group *group;
+       struct exclude_list *el;
+       struct exclude_stack *stk;
+
+       for (i = EXC_CMDL; i <= EXC_FILE; i++) {
+               group = &dir->exclude_list_group[i];
+               for (j = 0; j < group->nr; j++) {
+                       el = &group->el[j];
+                       if (i == EXC_DIRS)
+                               free((char *)el->src);
+                       clear_exclude_list(el);
+               }
+               free(group->el);
+       }
+
+       stk = dir->exclude_stack;
+       while (stk) {
+               struct exclude_stack *prev = stk->prev;
+               free(stk);
+               stk = prev;
+       }
+}
diff --git a/dir.h b/dir.h
index 64c410e13261e6a0fa0521d49da4fe5d654045e8..dd42a3a0614b10c1f522321db9c3a638cadbceac 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -169,6 +169,7 @@ extern void parse_exclude_pattern(const char **string, int *patternlen, int *fla
 extern void add_exclude(const char *string, const char *base,
                        int baselen, struct exclude_list *el, int srcpos);
 extern void clear_exclude_list(struct exclude_list *el);
+extern void clear_directory(struct dir_struct *dir);
 extern int file_exists(const char *);
 
 extern int is_inside_dir(const char *dir);