* [PATCH 1/4] Start to replace locate_rename_dst() with a generic function.
2010-11-04 20:33 [RFC PATCH] generalizing sorted-array handling Yann Dirson
@ 2010-11-04 20:33 ` Yann Dirson
2010-11-04 20:45 ` Jonathan Nieder
2010-11-04 20:33 ` [PATCH 2/4] Abstract _locate_element() some more with elem_size parameter Yann Dirson
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Yann Dirson @ 2010-11-04 20:33 UTC (permalink / raw)
To: git; +Cc: Yann Dirson
First we introduce the trivial changes: replace hardcoded references to
rename_dst_nr, rename_dst_alloc to parameters.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
diffcore-rename.c | 25 ++++++++++++++++---------
1 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index df41be5..fc554e4 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -6,6 +6,10 @@
#include "diffcore.h"
#include "hash.h"
+#define locate_element(list,elem,insert_ok) \
+ _locate_element(elem, &list##_nr, &list##_alloc, \
+ insert_ok)
+
/* Table of rename/copy destinations */
static struct diff_rename_dst {
@@ -13,14 +17,17 @@ static struct diff_rename_dst {
struct diff_filepair *pair;
} *rename_dst;
static int rename_dst_nr, rename_dst_alloc;
+#define locate_rename_dst(elem,insert_ok) \
+ locate_element(rename_dst, elem, insert_ok)
-static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
- int insert_ok)
+static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
+ int *elem_nr_p, int *elem_alloc_p,
+ int insert_ok)
{
int first, last;
first = 0;
- last = rename_dst_nr;
+ last = (*elem_nr_p);
while (last > first) {
int next = (last + first) >> 1;
struct diff_rename_dst *dst = &(rename_dst[next]);
@@ -37,15 +44,15 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
if (!insert_ok)
return NULL;
/* insert to make it at "first" */
- if (rename_dst_alloc <= rename_dst_nr) {
- rename_dst_alloc = alloc_nr(rename_dst_alloc);
+ if ((*elem_alloc_p) <= (*elem_nr_p)) {
+ (*elem_alloc_p) = alloc_nr(*elem_alloc_p);
rename_dst = xrealloc(rename_dst,
- rename_dst_alloc * sizeof(*rename_dst));
+ (*elem_alloc_p) * sizeof(*rename_dst));
}
- rename_dst_nr++;
- if (first < rename_dst_nr)
+ (*elem_nr_p)++;
+ if (first < (*elem_nr_p))
memmove(rename_dst + first + 1, rename_dst + first,
- (rename_dst_nr - first - 1) * sizeof(*rename_dst));
+ ((*elem_nr_p) - first - 1) * sizeof(*rename_dst));
rename_dst[first].two = alloc_filespec(two->path);
fill_filespec(rename_dst[first].two, two->sha1, two->mode);
rename_dst[first].pair = NULL;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] Start to replace locate_rename_dst() with a generic function.
2010-11-04 20:33 ` [PATCH 1/4] Start to replace locate_rename_dst() with a generic function Yann Dirson
@ 2010-11-04 20:45 ` Jonathan Nieder
2010-11-04 21:22 ` Yann Dirson
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Nieder @ 2010-11-04 20:45 UTC (permalink / raw)
To: Yann Dirson; +Cc: git
Yann Dirson wrote:
> --- a/diffcore-rename.c
> +++ b/diffcore-rename.c
> @@ -6,6 +6,10 @@
> #include "diffcore.h"
> #include "hash.h"
>
> +#define locate_element(list,elem,insert_ok) \
> + _locate_element(elem, &list##_nr, &list##_alloc, \
> + insert_ok)
> +
Is this syntactic sugar needed?
static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
insert_ok)
{
return locate_element(&rename_dst_nr, &rename_dst_alloc, elem, insert_ok);
}
takes more advantage of the compiler's typechecking and looks easy
enough to read.
Since this is local to diffcore-rename, I don't mind the locate_element()
name, but if this is to be used more widely I think it would need to be
named more precisely. (find_or_insert_in_array()?)
> @@ -13,14 +17,17 @@ static struct diff_rename_dst {
[...]
> -static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
> - int insert_ok)
> +static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
> + int *elem_nr_p, int *elem_alloc_p,
> + int insert_ok)
> {
> int first, last;
>
> first = 0;
> - last = rename_dst_nr;
> + last = (*elem_nr_p);
I guess these parentheses came from search+replace? It's more
readable without them.
[...]
> + (*elem_nr_p)++;
Except for this one.
Generally, the approach seems sane so far.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] Start to replace locate_rename_dst() with a generic function.
2010-11-04 20:45 ` Jonathan Nieder
@ 2010-11-04 21:22 ` Yann Dirson
0 siblings, 0 replies; 8+ messages in thread
From: Yann Dirson @ 2010-11-04 21:22 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
On Thu, Nov 04, 2010 at 03:45:55PM -0500, Jonathan Nieder wrote:
> static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
> insert_ok)
> {
> return locate_element(&rename_dst_nr, &rename_dst_alloc, elem, insert_ok);
> }
The idea was to deprecate locate_rename_dst() itself and only use
locate_element()...
> takes more advantage of the compiler's typechecking and looks easy
> enough to read.
... but typechecking was something that was worrying me here. Looks
like a good idea, after all.
> Since this is local to diffcore-rename, I don't mind the locate_element()
> name, but if this is to be used more widely I think it would need to be
> named more precisely. (find_or_insert_in_array()?)
Yes - that's just a prototype.
> I guess these parentheses came from search+replace? It's more
> readable without them.
Right, many of them are superfluous.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/4] Abstract _locate_element() some more with elem_size parameter.
2010-11-04 20:33 [RFC PATCH] generalizing sorted-array handling Yann Dirson
2010-11-04 20:33 ` [PATCH 1/4] Start to replace locate_rename_dst() with a generic function Yann Dirson
@ 2010-11-04 20:33 ` Yann Dirson
2010-11-04 20:33 ` [PATCH 3/4] Introduce "abstract class" to make _locate_element() more independant of diff_rename_dst Yann Dirson
2010-11-04 20:33 ` [PATCH 4/4] Remove remaining rename_dst references in _locate_element() and pass a pointer to it Yann Dirson
3 siblings, 0 replies; 8+ messages in thread
From: Yann Dirson @ 2010-11-04 20:33 UTC (permalink / raw)
To: git; +Cc: Yann Dirson
Now offset calculations don't rely on pointer arithmetic any more, paving
the way for complete decoupling from diff_rename_dst.
---
diffcore-rename.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index fc554e4..6e7ab4a 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -8,7 +8,7 @@
#define locate_element(list,elem,insert_ok) \
_locate_element(elem, &list##_nr, &list##_alloc, \
- insert_ok)
+ sizeof(*list), insert_ok)
/* Table of rename/copy destinations */
@@ -22,15 +22,16 @@ static int rename_dst_nr, rename_dst_alloc;
static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
int *elem_nr_p, int *elem_alloc_p,
- int insert_ok)
+ size_t elem_size, int insert_ok)
{
int first, last;
+ struct diff_rename_dst *first_elem_p;
first = 0;
last = (*elem_nr_p);
while (last > first) {
int next = (last + first) >> 1;
- struct diff_rename_dst *dst = &(rename_dst[next]);
+ struct diff_rename_dst *dst = (void*)rename_dst + (next * elem_size);
int cmp = strcmp(two->path, dst->two->path);
if (!cmp)
return dst;
@@ -47,16 +48,18 @@ static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
if ((*elem_alloc_p) <= (*elem_nr_p)) {
(*elem_alloc_p) = alloc_nr(*elem_alloc_p);
rename_dst = xrealloc(rename_dst,
- (*elem_alloc_p) * sizeof(*rename_dst));
+ (*elem_alloc_p) * elem_size);
}
(*elem_nr_p)++;
+ first_elem_p = (void*)rename_dst + first * elem_size;
if (first < (*elem_nr_p))
- memmove(rename_dst + first + 1, rename_dst + first,
- ((*elem_nr_p) - first - 1) * sizeof(*rename_dst));
- rename_dst[first].two = alloc_filespec(two->path);
- fill_filespec(rename_dst[first].two, two->sha1, two->mode);
- rename_dst[first].pair = NULL;
- return &(rename_dst[first]);
+ memmove((void*)rename_dst + (first + 1) * elem_size,
+ first_elem_p,
+ ((*elem_nr_p) - first - 1) * elem_size);
+ first_elem_p->two = alloc_filespec(two->path);
+ fill_filespec(first_elem_p->two, two->sha1, two->mode);
+ first_elem_p->pair = NULL;
+ return first_elem_p;
}
/* Table of rename/copy src files */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/4] Introduce "abstract class" to make _locate_element() more independant of diff_rename_dst.
2010-11-04 20:33 [RFC PATCH] generalizing sorted-array handling Yann Dirson
2010-11-04 20:33 ` [PATCH 1/4] Start to replace locate_rename_dst() with a generic function Yann Dirson
2010-11-04 20:33 ` [PATCH 2/4] Abstract _locate_element() some more with elem_size parameter Yann Dirson
@ 2010-11-04 20:33 ` Yann Dirson
2010-11-04 20:56 ` Jonathan Nieder
2010-11-04 20:33 ` [PATCH 4/4] Remove remaining rename_dst references in _locate_element() and pass a pointer to it Yann Dirson
3 siblings, 1 reply; 8+ messages in thread
From: Yann Dirson @ 2010-11-04 20:33 UTC (permalink / raw)
To: git; +Cc: Yann Dirson
The dst_obj struct acts as an absract base class for the elements which
_locate_element() manipulates arrays of.
---
diffcore-rename.c | 21 +++++++++++++--------
1 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 6e7ab4a..a674fbb 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -6,12 +6,16 @@
#include "diffcore.h"
#include "hash.h"
+
+/* "Abstract class" for lists of filespecs */
+struct dst_obj {
+ struct diff_filespec *two;
+};
#define locate_element(list,elem,insert_ok) \
_locate_element(elem, &list##_nr, &list##_alloc, \
sizeof(*list), insert_ok)
-/* Table of rename/copy destinations */
-
+/* Table of rename/copy destinations, "subclass" of dst_obj */
static struct diff_rename_dst {
struct diff_filespec *two;
struct diff_filepair *pair;
@@ -20,18 +24,18 @@ static int rename_dst_nr, rename_dst_alloc;
#define locate_rename_dst(elem,insert_ok) \
locate_element(rename_dst, elem, insert_ok)
-static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
- int *elem_nr_p, int *elem_alloc_p,
- size_t elem_size, int insert_ok)
+static void *_locate_element(struct diff_filespec *two,
+ int *elem_nr_p, int *elem_alloc_p,
+ size_t elem_size, int insert_ok)
{
int first, last;
- struct diff_rename_dst *first_elem_p;
+ struct dst_obj *first_elem_p;
first = 0;
last = (*elem_nr_p);
while (last > first) {
int next = (last + first) >> 1;
- struct diff_rename_dst *dst = (void*)rename_dst + (next * elem_size);
+ struct dst_obj *dst = (void*)rename_dst + (next * elem_size);
int cmp = strcmp(two->path, dst->two->path);
if (!cmp)
return dst;
@@ -58,7 +62,8 @@ static struct diff_rename_dst *_locate_element(struct diff_filespec *two,
((*elem_nr_p) - first - 1) * elem_size);
first_elem_p->two = alloc_filespec(two->path);
fill_filespec(first_elem_p->two, two->sha1, two->mode);
- first_elem_p->pair = NULL;
+ memset(((struct dst_obj *)first_elem_p) + 1, 0,
+ elem_size - sizeof(struct dst_obj));
return first_elem_p;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] Introduce "abstract class" to make _locate_element() more independant of diff_rename_dst.
2010-11-04 20:33 ` [PATCH 3/4] Introduce "abstract class" to make _locate_element() more independant of diff_rename_dst Yann Dirson
@ 2010-11-04 20:56 ` Jonathan Nieder
0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Nieder @ 2010-11-04 20:56 UTC (permalink / raw)
To: Yann Dirson; +Cc: git
Yann Dirson wrote:
> --- a/diffcore-rename.c
> +++ b/diffcore-rename.c
> @@ -6,12 +6,16 @@
> #include "diffcore.h"
> #include "hash.h"
>
> +
> +/* "Abstract class" for lists of filespecs */
> +struct dst_obj {
> + struct diff_filespec *two;
> +};
> #define locate_element(list,elem,insert_ok) \
> _locate_element(elem, &list##_nr, &list##_alloc, \
> sizeof(*list), insert_ok)
>
> -/* Table of rename/copy destinations */
> -
> +/* Table of rename/copy destinations, "subclass" of dst_obj */
> static struct diff_rename_dst {
> struct diff_filespec *two;
Nit: language lawyers might be happier with:
struct dst_obj {
struct diff_filespec *spec
};
struct diff_rename_dst {
struct dst_obj two;
...
};
or
typedef struct diff_filespec *dst_obj;
struct diff_rename_dst {
dst_obj two;
...
};
or
struct diff_rename_dst {
struct diff_filespec *two;
...
};
...
struct diff_filespec **dst = (const char *) rename_dst + next * elem_size;
to avoid violating strict aliasing rules.
Meanwhile, something like
#define container_of(ptr, type, member) \
((type *)((char *) ptr - offsetof(type, member)))
can be useful for making the meaning more obvious when downcasting.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/4] Remove remaining rename_dst references in _locate_element() and pass a pointer to it.
2010-11-04 20:33 [RFC PATCH] generalizing sorted-array handling Yann Dirson
` (2 preceding siblings ...)
2010-11-04 20:33 ` [PATCH 3/4] Introduce "abstract class" to make _locate_element() more independant of diff_rename_dst Yann Dirson
@ 2010-11-04 20:33 ` Yann Dirson
3 siblings, 0 replies; 8+ messages in thread
From: Yann Dirson @ 2010-11-04 20:33 UTC (permalink / raw)
To: git; +Cc: Yann Dirson
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
diffcore-rename.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index a674fbb..a4e0a96 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -11,8 +11,8 @@
struct dst_obj {
struct diff_filespec *two;
};
-#define locate_element(list,elem,insert_ok) \
- _locate_element(elem, &list##_nr, &list##_alloc, \
+#define locate_element(list,elem,insert_ok) \
+ _locate_element((void**)&list, elem, &list##_nr, &list##_alloc, \
sizeof(*list), insert_ok)
/* Table of rename/copy destinations, "subclass" of dst_obj */
@@ -24,7 +24,7 @@ static int rename_dst_nr, rename_dst_alloc;
#define locate_rename_dst(elem,insert_ok) \
locate_element(rename_dst, elem, insert_ok)
-static void *_locate_element(struct diff_filespec *two,
+static void *_locate_element(void **listp, struct diff_filespec *two,
int *elem_nr_p, int *elem_alloc_p,
size_t elem_size, int insert_ok)
{
@@ -35,7 +35,7 @@ static void *_locate_element(struct diff_filespec *two,
last = (*elem_nr_p);
while (last > first) {
int next = (last + first) >> 1;
- struct dst_obj *dst = (void*)rename_dst + (next * elem_size);
+ struct dst_obj *dst = *listp + (next * elem_size);
int cmp = strcmp(two->path, dst->two->path);
if (!cmp)
return dst;
@@ -51,13 +51,12 @@ static void *_locate_element(struct diff_filespec *two,
/* insert to make it at "first" */
if ((*elem_alloc_p) <= (*elem_nr_p)) {
(*elem_alloc_p) = alloc_nr(*elem_alloc_p);
- rename_dst = xrealloc(rename_dst,
- (*elem_alloc_p) * elem_size);
+ *listp = xrealloc(*listp, (*elem_alloc_p) * elem_size);
}
(*elem_nr_p)++;
- first_elem_p = (void*)rename_dst + first * elem_size;
+ first_elem_p = *listp + first * elem_size;
if (first < (*elem_nr_p))
- memmove((void*)rename_dst + (first + 1) * elem_size,
+ memmove(*listp + (first + 1) * elem_size,
first_elem_p,
((*elem_nr_p) - first - 1) * elem_size);
first_elem_p->two = alloc_filespec(two->path);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread