[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: modules for generic unordered sets and mappings

From: Bruno Haible
Subject: Re: RFC: modules for generic unordered sets and mappings
Date: Sun, 4 Jul 2010 14:30:32 +0200
User-agent: KMail/1.9.9

Jim Meyering wrote:
> I think the goal of this function is to return the single (first?)
> KEY-matching entry from the set ...
> ...
> Think of set of composite values (a struct), of which
> one serves as a key.  You may want to query whether a
> dummy { key, x, y, z } is in the set, solely to find
> some real element with a matching key.

Yes, exactly. By the fact that the user can specify the equality function
and the hash function, two keys may be equal that are not == as pointers.
This can be used to store payload on the key's side. For example, in gettext,
we have
  typedef struct { msgid; msgstr; } *message_t;
The equality function compares only the msgid field of the message, but the
programmer is of course also interested in the msgstr part.

A similar use case is for uniquifying tables. These are conceptually a mapping
from a key to a canonical instance of the key, so that the value compares
equal to the key. If you implement this as a set rather than as a mapping,
you save memory.

> But then, is the set merely a special case of a map?

Yes it is. The programmer could also store the payload in a separate value.
But if the data structures of the program already store the payload with
the key, it can be viewed as a set.

> I would prefer one like this:
>   bool gl_set_search (..., void const *key, void **match);
> so as not to limit the range of valid "void*" result values.

I have a slight preference for

    void * gl_set_search (..., void const *key, bool *foundp);

because the user's value type most often is a 'foo_t *', not 'void *',
and in the first case if he declares a variable of type 'foo_t *',
he has to cast the pointer, breaking strict-aliasing rules. In the
second case the assignment from 'void *' to 'foo_t *' does not break
strict-aliasing rules.

Jose E. Marchesi wrote:
> The returned entry would be something like 'gl_list_node_t', right?

Good point. For the mapping data structure, I'll bear this in mind.
So that after looking up a value you can store a new value without
performing the search a second time.

But for the set abstraction, you don't need a type like 'gl_list_node_t'.

> I am not sure what would be the benefit of returning
> something like 'gl_set_node_t' instead of the boolean directly.  In
> case we want to change the membership status for some key then we
> simply check and remove/insert.

For removals, you don't need a 'gl_set_node_t': just call the 'remove'
operation. For insertions, Jim has already suggested a "find or add"
a.k.a. "insert is not already contained" operation. When you have this
one, you don't need 'gl_set_node_t'.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]