summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: cb1491b)
raw | patch | inline | side by side (parent: cb1491b)
author | Linus Torvalds <torvalds@linux-foundation.org> | |
Thu, 25 Oct 2007 18:19:10 +0000 (11:19 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 27 Oct 2007 06:18:05 +0000 (23:18 -0700) |
Rather than copy the filespecs when introducing new versions of them
(for rename or copy detection), use a refcount and increment the count
when reusing the diff_filespec.
This avoids unnecessary allocations, but the real reason behind this is
a future enhancement: we will want to track shared data across the
copy/rename detection. In order to efficiently notice when a filespec
is used by a rename, the rename machinery wants to keep track of a
rename usage count which is shared across all different users of the
filespec.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
(for rename or copy detection), use a refcount and increment the count
when reusing the diff_filespec.
This avoids unnecessary allocations, but the real reason behind this is
a future enhancement: we will want to track shared data across the
copy/rename detection. In order to efficiently notice when a filespec
is used by a rename, the rename machinery wants to keep track of a
rename usage count which is shared across all different users of the
filespec.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff.c | patch | blob | history | |
diffcore-rename.c | patch | blob | history | |
diffcore.h | patch | blob | history |
index dfb8595b7086c71b3be0ece408d65a7285f42e9f..0b320f6b96fab017c2b32f3aa45921216d3f1e25 100644 (file)
--- a/diff.c
+++ b/diff.c
memset(spec, 0, sizeof(*spec));
spec->path = (char *)(spec + 1);
memcpy(spec->path, path, namelen+1);
+ spec->count = 1;
return spec;
}
+void free_filespec(struct diff_filespec *spec)
+{
+ if (!--spec->count) {
+ diff_free_filespec_data(spec);
+ free(spec);
+ }
+}
+
void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
unsigned short mode)
{
void diff_free_filepair(struct diff_filepair *p)
{
- diff_free_filespec_data(p->one);
- diff_free_filespec_data(p->two);
- free(p->one);
- free(p->two);
+ free_filespec(p->one);
+ free_filespec(p->two);
free(p);
}
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 2077a9b981945dd2a75cbf8a867738ccf1de30c8..3da06b702bf2ee0381f1bb75ff5a7d04026d14ac 100644 (file)
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
static void record_rename_pair(int dst_index, int src_index, int score)
{
- struct diff_filespec *one, *two, *src, *dst;
+ struct diff_filespec *src, *dst;
struct diff_filepair *dp;
if (rename_dst[dst_index].pair)
die("internal error: dst already matched.");
src = rename_src[src_index].one;
- one = alloc_filespec(src->path);
- fill_filespec(one, src->sha1, src->mode);
+ src->count++;
dst = rename_dst[dst_index].two;
- two = alloc_filespec(dst->path);
- fill_filespec(two, dst->sha1, dst->mode);
+ dst->count++;
- dp = diff_queue(NULL, one, two);
+ dp = diff_queue(NULL, src, dst);
dp->renamed_pair = 1;
if (!strcmp(src->path, dst->path))
dp->score = rename_src[src_index].score;
}
}
- for (i = 0; i < rename_dst_nr; i++) {
- diff_free_filespec_data(rename_dst[i].two);
- free(rename_dst[i].two);
- }
+ for (i = 0; i < rename_dst_nr; i++)
+ free_filespec(rename_dst[i].two);
free(rename_dst);
rename_dst = NULL;
diff --git a/diffcore.h b/diffcore.h
index eb618b1ec00113dabcd5231f141f82e1cdfdca46..30055ac5a9692f0f1f952de0754f36221cd07664 100644 (file)
--- a/diffcore.h
+++ b/diffcore.h
void *cnt_data;
const char *funcname_pattern_ident;
unsigned long size;
+ int count; /* Reference count */
int xfrm_flags; /* for use by the xfrm */
unsigned short mode; /* file mode */
unsigned sha1_valid : 1; /* if true, use sha1 and trust mode;
};
extern struct diff_filespec *alloc_filespec(const char *);
+extern void free_filespec(struct diff_filespec *);
extern void fill_filespec(struct diff_filespec *, const unsigned char *,
unsigned short);