Boost logo

Boost :

Subject: Re: [boost] interprocess with unordered_map
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2012-03-17 06:43:57

El 17/03/2012 5:53, Joel escribió:
> Ion Gaztañaga<igaztanaga<at>> writes:
>> El 15/03/2012 23:18, Olaf van der Spek escribió:
>>> 2012/3/15 Ion Gaztañaga<igaztanaga<at>>:
>>>> El 15/03/2012 3:14, Joel Young escribió:
>>>>> Can the interprocess::basic_string be modified to allow these conversions?
>>>>> I hate having to do:
>>>>> key_val = "fruitcake";
>>>>> db.find(key_val);
>>>> place the string in shared memory. I don' think it could be implicitly
>>>> constructible from char* or std::string.
> My code above used the assignment operator to convert it. The constructor can
> do it also. If not, then at least provide a convenience function to do it!
>>> But there's no (good) reason for the input to be required to be in
>>> shared memory.
> Exactly. I've got my container in the mapped file or shared memory. Why should
> I want to clutter up the shared memory with a temporary? Especially if I'm just
> doing a find in a read-only chunk of memory!
>> A shared memory allocator is designed to allocate from a managed shared
>> memory segment. And this requires a base address of that shared memory
>> segment . And even with std::string you need to build a temporary string
>> to compare it with the ones stored in the container.
> But the temporary string isn't used for anything! I create a temporary string,
> allocated into a DIFFERENT memory pool and it works just fine. If I can create
> an arbitrary basic_string with an allocator to a random place to serve as a
> temporary, the library can darn well do it too!

Ok, but this is a different issue. We still need to create a temporary
string (and allocate dynamic memory, in shared memory, heap, etc... ) so
you don't get any free comparison. Your original statement was:

"I have to do gymcrackery like:

key_type key_val(stupid.get_segment_manager());

to create a temporary to allow me to search since the maps find() method
will only take a key_type and interprocess::basic_string WILL NOT
implicitly construct from a std::string, nor will it implicitly
construct from a char* to itself.

Can the interprocess::basic_string be modified to allow these conversions?"

No basic_string change will change the fact that you need to create a
temporary (explicit or implicit) to find a value, as unordered requires
it. Changing basic_string with implicit conversions to save some
keystrokes will do much more harm than good. And you can reuse that
explicit temporary if you search several keys in a loop obtaining much
better performance.

If we want to achieve direct comparison, Boost.Unordered needs to go
Boost.Intrusive or Boost.Multiindex route, and offer additional search
overloads that can find "equivalent keys":

I think the annoyance of writing a temporary string is much better than
changing boost::container::basic_string (which knows nothing about
shared memory as it's an std::string-like class) with conversions that
will bring a lot of overload problems.

The only point that I consider negative is that we need to allocate
memory in a shared memory segment to do a comparison. Maybe we have no
write access to shared memory (open_read_only flag) and having to
allocate memory will ruin this advantage.

A solution for this is to find a way to explicitly build an special
temporary of type basic_string< T, boost::interprocess::allocator<> >
that will hold the string in heap. I won't make this implicit (say, a
default constructed boost::interprocess::allocator) as otherwise tons of
new users will start having problems thinking they've placed a string in
shm when they are actually building it in the heap).


Boost list run by bdawes at, gregod at, cpdaniel at, john at