RelNotes: spelling & grammar tweaks

Signed-off-by: Marc Branchaud <marcnarc@xiplink.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Git 2.2

Signed-off-by: Junio C Hamano <gitster@pobox.com>
make "struct counted_string" available everywhere

This is a handy convenience struct to pair a pointer and a
length. It can be used when you need to pass both through a
single void pointer. It's already defined and used in
remote.c, but we could make use of it elsewhere.
hashmap: split comparison into two functions

When a hashmap is initialized, the caller gives it a
comparison function to disambiguate entries with the same
hash. Ideally, the comparison function for a hash
containing "struct foo" would just take two "struct foo *"
poitners and tell the hash whether they're equal.

However, when looking up a value, it's not practical to ask
that the caller already have a fully formed "struct foo" to
pass.  They might have the data in a different form, and it
may be costly to create a "struct foo" (e.g., if it contains
a FLEX_ARRAY and we would have to allocate a whole struct).
For that reason, hashmap provides an extra "keydata"
parameter, which gets passed to the comparator. You can pass
a half-formed "struct foo", and then pass the rest of the
data via "keydata".

This ends up making comparators confusing to write, as you
are really covering two cases: one in which you are really
comparing two entries, and one in which you are comparing a
key in arbitrary format to existing entries. In the latter
case, you have a half-formed "struct foo", and you can only
look at certain entries (and have to replace them with
values from "keydata").

Instead, we can provide two comparison functions. One
which will take two "struct foo" pointers and compare their
values, and one which will take a "struct foo" and another
arbitrary opaque data type and compare them.

The upside is that the comparators are much easier to
understand. There are two downsides, though:

  1. It's more verbose. You're writing two functions instead
     of one.  Often one can be written in terms of the other,
     or it's trivial to share a common implementation, so
     this is really just a matter of lines of code, not of
     increased complexity (in fact, the complexity should
     hopefully be less).

  2. The key data type must encapsulate all of the data.
     In cases where "struct foo" contains a FLEX_ARRAY and
     "keydata" is a pointer to the bytes that would be found
     in the array, you can do something like:

       struct foo key;
       hashmap_entry_init(&key, memhash(data, len));
       key.len = len;
       hashmap_get(map, &key, data);

     In other words, you really care comparing the "struct
     foo", but you're just "augmenting" it with the extra
     data in keydata (and the comparator must know how to
     apply that augmentation; it looks at foo.len, but
     "keydata" instead of foo->data).

     But with a separate structure, you may need an extra
     data type. For example, you need some way of binding
     the data and length into a single pointer, like:

       struct hashmap_entry entry;
       struct counted_string key;

       hashmap_entry_init(&key, memhash(data, len));
       key.str = data;
       key.len = len;
       hashmap_get(map, &entry, &key);

     In most cases (in fact all that are currently present)
     this "counted_string" type is sufficient, and can be
     reused without having to define a new type.

This patch makes such a split. While we are there, it also
flips the boolean sense of the equality functions. Calling
these functions "foo_cmp" does not follow our usual pattern,
which would imply that "foo_cmp" can be used both for
equality tests (as "!foo_cmp") and for ordering (i.e., that
the sign bit of foo_cmp's return is useful). Some
comparators do provide that, but others do not. Instead,
let's call it "foo_equals", which reinforces that it's a
pure equality test.

It also tends to make the comparator code itself easier to
follow, as we do not need extra negations inside it. We can
write:

  return a->len == b->len && !memcmp(a->data, b->data, a->len);

instead of:

  return a->len != b->len || memcmp(a->data, b->data, a->len);

All of the existing callers are updated.