git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] hashmap: adjust documentation to reflect reality
@ 2017-11-29 23:51 Johannes Schindelin
  2017-11-30  0:16 ` Jonathan Nieder
  2017-11-30  3:07 ` Jeff King
  0 siblings, 2 replies; 7+ messages in thread
From: Johannes Schindelin @ 2017-11-29 23:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Stefan Beller

The hashmap API is just complicated enough that even at least one
long-time Git contributor has to look up how to use it every time he
finds a new use case. When that happens, it is really useful if the
provided example code is correct...

While at it, "fix a memory leak", avoid statements before variable
declarations, fix a const -> no-const cast, several %l specifiers (which
want to be %ld), avoid using an undefined constant, call scanf()
correctly, use FLEX_ALLOC_STR() where appropriate, and adjust the style
here and there.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 hashmap.h | 60 +++++++++++++++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

diff --git a/hashmap.h b/hashmap.h
index 7cb29a6aede..7ce79f3f72c 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -18,75 +18,71 @@
  *
  * #define COMPARE_VALUE 1
  *
- * static int long2string_cmp(const struct long2string *e1,
+ * static int long2string_cmp(const void *hashmap_cmp_fn_data,
+ *                            const struct long2string *e1,
  *                            const struct long2string *e2,
- *                            const void *keydata, const void *userdata)
+ *                            const void *keydata)
  * {
- *     char *string = keydata;
- *     unsigned *flags = (unsigned*)userdata;
+ *     const char *string = keydata;
+ *     unsigned flags = *(unsigned *)hashmap_cmp_fn_data;
  *
  *     if (flags & COMPARE_VALUE)
- *         return !(e1->key == e2->key) || (keydata ?
- *                  strcmp(e1->value, keydata) : strcmp(e1->value, e2->value));
+ *         return e1->key != e2->key ||
+ *                  strcmp(e1->value, string ? string : e2->value);
  *     else
- *         return !(e1->key == e2->key);
+ *         return e1->key != e2->key;
  * }
  *
  * int main(int argc, char **argv)
  * {
  *     long key;
- *     char *value, *action;
- *
- *     unsigned flags = ALLOW_DUPLICATE_KEYS;
+ *     char value[255], action[32];
+ *     unsigned flags = 0;
  *
  *     hashmap_init(&map, (hashmap_cmp_fn) long2string_cmp, &flags, 0);
  *
- *     while (scanf("%s %l %s", action, key, value)) {
+ *     while (scanf("%s %ld %s", action, &key, value)) {
  *
  *         if (!strcmp("add", action)) {
  *             struct long2string *e;
- *             e = malloc(sizeof(struct long2string) + strlen(value));
+ *             FLEX_ALLOC_STR(e, value, value);
  *             hashmap_entry_init(e, memhash(&key, sizeof(long)));
  *             e->key = key;
- *             memcpy(e->value, value, strlen(value));
  *             hashmap_add(&map, e);
  *         }
  *
  *         if (!strcmp("print_all_by_key", action)) {
- *             flags &= ~COMPARE_VALUE;
- *
- *             struct long2string k;
+ *             struct long2string k, *e;
  *             hashmap_entry_init(&k, memhash(&key, sizeof(long)));
  *             k.key = key;
  *
- *             struct long2string *e = hashmap_get(&map, &k, NULL);
+ *             flags &= ~COMPARE_VALUE;
+ *             e = hashmap_get(&map, &k, NULL);
  *             if (e) {
- *                 printf("first: %l %s\n", e->key, e->value);
- *                 while (e = hashmap_get_next(&map, e))
- *                     printf("found more: %l %s\n", e->key, e->value);
+ *                 printf("first: %ld %s\n", e->key, e->value);
+ *                 while ((e = hashmap_get_next(&map, e)))
+ *                     printf("found more: %ld %s\n", e->key, e->value);
  *             }
  *         }
  *
  *         if (!strcmp("has_exact_match", action)) {
- *             flags |= COMPARE_VALUE;
- *
  *             struct long2string *e;
- *             e = malloc(sizeof(struct long2string) + strlen(value));
+ *             FLEX_ALLOC_STR(e, value, value);
  *             hashmap_entry_init(e, memhash(&key, sizeof(long)));
  *             e->key = key;
- *             memcpy(e->value, value, strlen(value));
  *
- *             printf("%s found\n", hashmap_get(&map, e, NULL) ? "" : "not");
+ *             flags |= COMPARE_VALUE;
+ *             printf("%sfound\n", hashmap_get(&map, e, NULL) ? "" : "not ");
+ *             free(e);
  *         }
  *
  *         if (!strcmp("has_exact_match_no_heap_alloc", action)) {
- *             flags |= COMPARE_VALUE;
- *
- *             struct long2string e;
- *             hashmap_entry_init(e, memhash(&key, sizeof(long)));
- *             e.key = key;
+ *             struct long2string k;
+ *             hashmap_entry_init(&k, memhash(&key, sizeof(long)));
+ *             k.key = key;
  *
- *             printf("%s found\n", hashmap_get(&map, e, value) ? "" : "not");
+ *             flags |= COMPARE_VALUE;
+ *             printf("%sfound\n", hashmap_get(&map, &k, value) ? "" : "not ");
  *         }
  *
  *         if (!strcmp("end", action)) {
@@ -94,6 +90,8 @@
  *             break;
  *         }
  *     }
+ *
+ *     return 0;
  * }
  */
 

base-commit: 1a4e40aa5dc16564af879142ba9dfbbb88d1e5ff
-- 
2.15.0.windows.1.22.g2b9dc9b294f

Published-As: https://github.com/dscho/git/releases/tag/fix-hashmap-documentation-v1
Fetch-It-Via: git fetch https://github.com/dscho/git fix-hashmap-documentation-v1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-11-29 23:51 [PATCH] hashmap: adjust documentation to reflect reality Johannes Schindelin
@ 2017-11-30  0:16 ` Jonathan Nieder
  2017-11-30  3:07 ` Jeff King
  1 sibling, 0 replies; 7+ messages in thread
From: Jonathan Nieder @ 2017-11-30  0:16 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Junio C Hamano, Stefan Beller

Johannes Schindelin wrote:

> The hashmap API is just complicated enough that even at least one
> long-time Git contributor has to look up how to use it every time he
> finds a new use case. When that happens, it is really useful if the
> provided example code is correct...
>
> While at it, "fix a memory leak", avoid statements before variable
> declarations, fix a const -> no-const cast, several %l specifiers (which
> want to be %ld), avoid using an undefined constant, call scanf()
> correctly, use FLEX_ALLOC_STR() where appropriate, and adjust the style
> here and there.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  hashmap.h | 60 +++++++++++++++++++++++++++++-------------------------------
>  1 file changed, 29 insertions(+), 31 deletions(-)

Yay, thanks for this.

Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

Follow-on idea for the interested: would making a test that extracts
this sample code from hashmap.h and confirms it still works be a crazy
idea?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-11-29 23:51 [PATCH] hashmap: adjust documentation to reflect reality Johannes Schindelin
  2017-11-30  0:16 ` Jonathan Nieder
@ 2017-11-30  3:07 ` Jeff King
  2017-12-03  5:35   ` Junio C Hamano
  1 sibling, 1 reply; 7+ messages in thread
From: Jeff King @ 2017-11-30  3:07 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Junio C Hamano, Stefan Beller

On Thu, Nov 30, 2017 at 12:51:41AM +0100, Johannes Schindelin wrote:

> The hashmap API is just complicated enough that even at least one
> long-time Git contributor has to look up how to use it every time he
> finds a new use case. When that happens, it is really useful if the
> provided example code is correct...
> 
> While at it, "fix a memory leak", avoid statements before variable
> declarations, fix a const -> no-const cast, several %l specifiers (which
> want to be %ld), avoid using an undefined constant, call scanf()
> correctly, use FLEX_ALLOC_STR() where appropriate, and adjust the style
> here and there.

Heh, that's quite a list of faults for what's supposed to be simple
example code. ;)

Your improvements all look good to me, and I'd be happy to see this
applied as-is. But here are two possible suggestions:

> diff --git a/hashmap.h b/hashmap.h
> index 7cb29a6aede..7ce79f3f72c 100644
> --- a/hashmap.h
> +++ b/hashmap.h
> @@ -18,75 +18,71 @@
>   *
>   * #define COMPARE_VALUE 1
>   *
> - * static int long2string_cmp(const struct long2string *e1,
> + * static int long2string_cmp(const void *hashmap_cmp_fn_data,
> + *                            const struct long2string *e1,
>   *                            const struct long2string *e2,
> - *                            const void *keydata, const void *userdata)
> + *                            const void *keydata)

If these struct pointers became "const void *", then we would not need
to cast the function pointer here:

>   *     hashmap_init(&map, (hashmap_cmp_fn) long2string_cmp, &flags, 0);

which would mean that the original problem you are fixing would have
been caught by the compiler, rather than probably segfaulting at
runtime.

My second suggestion (which I'm on the fence about) is: would it better
to just say "see t/helper/test-hashmap.c for a representative example?"

I'm all for code examples in documentation, but this one is quite
complex. The code in test-hashmap.c is not much more complex, and is at
least guaranteed to compile and run. It doesn't show off how to combine
a flex-array with a hashmap as well, but I'm not sure how important that
is. So I could go either way.

-Peff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-11-30  3:07 ` Jeff King
@ 2017-12-03  5:35   ` Junio C Hamano
  2017-12-04 19:08     ` Stefan Beller
  0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2017-12-03  5:35 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin, git, Stefan Beller

Jeff King <peff@peff.net> writes:

> My second suggestion (which I'm on the fence about) is: would it better
> to just say "see t/helper/test-hashmap.c for a representative example?"

I also had the same thought.  It is rather unwieldy to ask people to
lift code from comment text, and it is also hard to maintain such a
commented out code to make sure it is up to date.

> I'm all for code examples in documentation, but this one is quite
> complex. The code in test-hashmap.c is not much more complex, and is at
> least guaranteed to compile and run.

Yup.  Exactly.

> It doesn't show off how to combine a flex-array with a hashmap as
> well, but I'm not sure how important that is. So I could go either
> way.

Likewise.

In any case, keeping a bad example as-is is less good than replacing
it with a corrected one, so I do not mind taking this patch as an
immediate first step, whether we later decide to remove it and refer
to an external file that has a real example that will be easier to
maintain and use.

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-12-03  5:35   ` Junio C Hamano
@ 2017-12-04 19:08     ` Stefan Beller
  2017-12-07 21:47       ` Johannes Schindelin
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Beller @ 2017-12-04 19:08 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Johannes Schindelin, git

On Sat, Dec 2, 2017 at 9:35 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jeff King <peff@peff.net> writes:
>
>> My second suggestion (which I'm on the fence about) is: would it better
>> to just say "see t/helper/test-hashmap.c for a representative example?"

I think that may be better in the long run, indeed.

>
> I also had the same thought.  It is rather unwieldy to ask people to
> lift code from comment text, and it is also hard to maintain such a
> commented out code to make sure it is up to date.
>
>> I'm all for code examples in documentation, but this one is quite
>> complex. The code in test-hashmap.c is not much more complex, and is at
>> least guaranteed to compile and run.
>
> Yup.  Exactly.
>
>> It doesn't show off how to combine a flex-array with a hashmap as
>> well, but I'm not sure how important that is. So I could go either
>> way.

We could add that example to the test helper as then we have a good (tested)
example for that case, too.

> In any case, keeping a bad example as-is is less good than replacing
> it with a corrected one, so I do not mind taking this patch as an
> immediate first step, whether we later decide to remove it and refer
> to an external file that has a real example that will be easier to
> maintain and use.
>
> Thanks.

Thanks for taking this and building on top,
Stefan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-12-04 19:08     ` Stefan Beller
@ 2017-12-07 21:47       ` Johannes Schindelin
  2017-12-08  9:03         ` Jeff King
  0 siblings, 1 reply; 7+ messages in thread
From: Johannes Schindelin @ 2017-12-07 21:47 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, Jeff King, git

Hi,

On Mon, 4 Dec 2017, Stefan Beller wrote:

> On Sat, Dec 2, 2017 at 9:35 PM, Junio C Hamano <gitster@pobox.com> wrote:
> > Jeff King <peff@peff.net> writes:
> >
> >> My second suggestion (which I'm on the fence about) is: would it better
> >> to just say "see t/helper/test-hashmap.c for a representative example?"
> 
> I think that may be better in the long run, indeed.

But we moved that example already out of the technical API documentation
into the hashmap.h file! Too much moving for my taste.

> > I also had the same thought.  It is rather unwieldy to ask people to
> > lift code from comment text, and it is also hard to maintain such a
> > commented out code to make sure it is up to date.
> >
> >> I'm all for code examples in documentation, but this one is quite
> >> complex. The code in test-hashmap.c is not much more complex, and is at
> >> least guaranteed to compile and run.
> >
> > Yup.  Exactly.
> >
> >> It doesn't show off how to combine a flex-array with a hashmap as
> >> well, but I'm not sure how important that is. So I could go either
> >> way.
> 
> We could add that example to the test helper as then we have a good (tested)
> example for that case, too.

What we could *also* do, and what would probably make *even more* sense,
is to simplify the example drastically, to a point where testing it in
test-hashmap is pointless, and where a reader can gather *very* quickly
what it takes to use the hashmap routines.

In any case, I would really like to see my patch applied first, as it is a
separate concern from what you gentle people talk about: I simply want
that incorrect documentation fixed. The earlier, the better.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] hashmap: adjust documentation to reflect reality
  2017-12-07 21:47       ` Johannes Schindelin
@ 2017-12-08  9:03         ` Jeff King
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff King @ 2017-12-08  9:03 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Stefan Beller, Junio C Hamano, git

On Thu, Dec 07, 2017 at 10:47:43PM +0100, Johannes Schindelin wrote:

> > We could add that example to the test helper as then we have a good (tested)
> > example for that case, too.
> 
> What we could *also* do, and what would probably make *even more* sense,
> is to simplify the example drastically, to a point where testing it in
> test-hashmap is pointless, and where a reader can gather *very* quickly
> what it takes to use the hashmap routines.

Yes, I'd be in favor of that, too.

> In any case, I would really like to see my patch applied first, as it is a
> separate concern from what you gentle people talk about: I simply want
> that incorrect documentation fixed. The earlier, the better.

Definitely. I think it is in "next" already.

-Peff

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-12-08  9:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-29 23:51 [PATCH] hashmap: adjust documentation to reflect reality Johannes Schindelin
2017-11-30  0:16 ` Jonathan Nieder
2017-11-30  3:07 ` Jeff King
2017-12-03  5:35   ` Junio C Hamano
2017-12-04 19:08     ` Stefan Beller
2017-12-07 21:47       ` Johannes Schindelin
2017-12-08  9:03         ` Jeff King

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).