[multi-index] retrieve unique keys of a non-unique index

Hi everyone (my apologies if this shows as a report),
In the following example is there a more efficient way to retrieve the
unique keys of a non-unique index?
#include
TaggedNodes;
int main()
{
TaggedNodes taggedNodes;
taggedNodes.insert(TaggedNodeEntry(1, 1, "one-one"));
taggedNodes.insert(TaggedNodeEntry(1, 2, "one-two"));
taggedNodes.insert(TaggedNodeEntry(1, 3, "one-three"));
taggedNodes.insert(TaggedNodeEntry(2, 1, "two-one"));
taggedNodes.insert(TaggedNodeEntry(2, 2, "two-two"));
taggedNodes.insert(TaggedNodeEntry(3, 6, "three-six"));
std::cout << std::endl << "Unique names :-" << std::endl;
boost::multi_index::index

On Thu, Aug 1, 2013 at 10:47 PM, Rory McCarthy < rorymccarthy77@googlemail.com> wrote:
In the following example is there a more efficient way to retrieve the unique keys of a non-unique index?
typedef multi_index_container< TaggedNodeEntry, indexed_by< hashed_non_unique< tag<name>, BOOST_MULTI_INDEX_MEMBER(**TaggedNodeEntry, int, name) >, ... >
TaggedNodes;
int main() { ... boost::multi_index::index<**TaggedNodes, name>::type::iterator ic0 = get<name>(taggedNodes).begin()**; boost::multi_index::index<**TaggedNodes, name>::type::iterator ic1 = get<name>(taggedNodes).end(); while (ic0 != ic1) { std::cout << ic0->name << std::endl; ic0 = get<name>(taggedNodes).equal_**range(ic0->name).second; }
Why not simply switch from hashed_non_unique to ordered_non_unique? That way you can full-scan that ordered index, and check yourself when the key changes, since you are guaranteed the entries will be clustered by the key, w/o resorting to equal_range() like for the hashed container. You lose a bit of speed for arbitrary lookups compared to the hashed index (not much I suspect), but should gain on getting the unique keys IMHO. --DD

El 01/08/2013 22:47, Rory McCarthy escribió:
Hi everyone (my apologies if this shows as a report),
In the following example is there a more efficient way to retrieve the unique keys of a non-unique index?
[...]
boost::multi_index::index

On Fri, Aug 2, 2013 at 9:36 AM, Joaquín Mª López Muñoz
std::unique_copy( get<name>(taggedNodes).begin(),get<name>(taggedNodes).end(), boost::make_function_output_iterator(&dump_entry_name), equal_entry_name); This is O(n), n being the number of total elements.
Ah yes, entries are clustered by keys during iteration whether ordered or hashed, I now realize. Thanks. Here's my STL-challenged version using BOOST_FOREACH. Less generic of course, but hopefully not buggy. --DD if (!get<name>(taggedNodes).empty()) { int curr_key = get<name>(taggedNodes).begin()->name; std::cout << curr_key << std::endl; BOOST_FOREACH (const TaggedNodeEntry& x, get<name>(taggedNodes)) { if (x.name != curr_key) { curr_key = x.name; std::cout << curr_key << std::endl; } } }

Thanks for the suggestions. I'm expecting that there will be relatively few
unique name keys, so using ordered_non_unique with O(m*log(n)) complexity
will definitely be more efficient,
On Fri, Aug 2, 2013 at 1:05 AM, Dominique Devienne
On Fri, Aug 2, 2013 at 9:36 AM, Joaquín Mª López Muñoz
wrote: std::unique_copy( get<name>(taggedNodes).begin(),get<name>(taggedNodes).end(), boost::make_function_output_iterator(&dump_entry_name), equal_entry_name); This is O(n), n being the number of total elements.
Ah yes, entries are clustered by keys during iteration whether ordered or hashed, I now realize. Thanks.
Here's my STL-challenged version using BOOST_FOREACH. Less generic of course, but hopefully not buggy. --DD
if (!get<name>(taggedNodes).empty()) { int curr_key = get<name>(taggedNodes).begin()->name; std::cout << curr_key << std::endl; BOOST_FOREACH (const TaggedNodeEntry& x, get<name>(taggedNodes)) { if (x.name != curr_key) { curr_key = x.name; std::cout << curr_key << std::endl; } } }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Dominique Devienne
-
Joaquín Mª López Muñoz
-
Rory McCarthy