flyweight - gsoc idea - multikey-value flyweight
Hi Joaquin,
I have a use case where I have several keys to the same flyweight.
I was trying to associate a multi-index as factory, but I don't see how
it could be done.
I believe that I would need something like a multikey_value
Vicente J. Botet Escriba
Hi Joaquin,
I have a use case where I have several keys to the same flyweight.
I was trying to associate a multi-index as factory, but I don't see how it could be done.
I believe that I would need something like a multikey_value
where KeyK should be deduced from KeyExtractorK.
Have you found this use case already?
Do you think this could be a good GSoC project?
Hi Vicente This is the first time I hear about such use case... intriguing. Can you elaborate a bit more? * Can you provide a motivating example? * What are the contidions in which flyweight(k1)==flyweight(k2), with type(k1)=K1, type(k2)=K2? Note that in the regular key-value case, identity of flyweights is defined as identity of keys. * How's this supposed to behave when K1=K2? Best Joaquín M López Muñoz Telefónica
Vicente J. Botet Escriba
writes: Hi Joaquin,
I have a use case where I have several keys to the same flyweight.
I was trying to associate a multi-index as factory, but I don't see how it could be done.
I believe that I would need something like a multikey_value
where KeyK should be deduced from KeyExtractorK.
Have you found this use case already?
Do you think this could be a good GSoC project? Hi Vicente
This is the first time I hear about such use case... intriguing. Can you elaborate a bit more?
* Can you provide a motivating example? Let say you are writing an application that manage with some entities. You have two kind of operator that use a specific protocol and each
Le 15/02/2016 07:51, Joaquin M LópezMuñoz a écrit : protocol identify these entities using a key MOi. Suppose that you application use a library that has an interface that use different keys to identify these same entities, because it is using an internal protocol. You want also to have some CLI for debugging purposes that uses strings to identify these same entities. All these keys are isomorphic so you can move from one key to the other using a specific algorithm. However this transformation could be more expensive than required. So you decide to store all these isomorphic keys in a AllKeys class. This class can be constructed from any key and deduce the others.You create the corresponding associative containers that give access to AllKeys from any of those keys. The application can store a smart pointer to this AllKeys object to identify the entity and all the mappings to all the external keys. IMO this is a particular case of multi-index where the stored object is const, and all the stored information can be deduced from any key. This is what I would expect a multi-key flyweight provide.
* What are the contidions in which flyweight(k1)==flyweight(k2), with type(k1)=K1, type(k2)=K2? Note that in the regular key-value case, identity of flyweights is defined as identity of keys. The keys must be isomorphic. * How's this supposed to behave when K1=K2?
It is supposed to don't compile ;-). The user will need to use tagged types to make the difference. In addition, in my application I have a not so big number of entities, so that I COULD create all the flyweight instances at compile time. Wondering if this particular case could have an implementation that performs better when the access is with done using constexpr keys. Best, Vicente
Vicente J. Botet Escriba
Le 15/02/2016 07:51, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Hi Joaquin,
I have a use case where I have several keys to the same flyweight.
[...]
Let say you are writing an application that manage with some entities. You have two kind of operator that use a specific protocol and each protocol identify these entities using a key MOi. Suppose that you application use a library that has an interface that use different keys to identify these same entities, because it is using an internal protocol. You want also to have some CLI for debugging purposes that uses strings to identify these same entities.
All these keys are isomorphic so you can move from one key to the other using a specific algorithm[...]
OK, let's sketch these ideas. Let's say
key1=int
key2=char
value=std::string
and we want to minimize conversion from keyi to keyj and construction
of values, because they're all expensive operations (not in this
particular case, but you get the idea). We make the converting functions
output to the console to keep track of if/when they're called:
char key2_from_key1(int i)
{
std::cout<<"key2_from_key1\n";
return static_cast<char>(i);
}
int key1_from_key2(char c)
{
std::cout<<"key1_from_key2\n";
return static_cast<int>(c);
}
std::string value_from_key1(int i)
{
std::cout<<"value_from_key1\n";
return boost::lexical_caststd::string(i);
}
std::string value_from_key2(char c)
{
std::cout<<"value_from_key2\n";
return boost::lexical_caststd::string(c);
}
Now, we can store all of this in an internal element class like:
struct element
{
int key1;
char key2;
std::string value;
element(int i):
key1{i},
key2{key2_from_key1(i)},
value{value_from_key1(i)}
{}
element(char c):
key1{key1_from_key2(c)},
key2{c},
value{value_from_key2(c)}
{}
};
(key1,value) flyweights are easy to define:
struct element_key1
{
const int& operator()(const element& e)const{return e.key1;}
};
using key1_flyweight=flyweight
Le 16/02/2016 16:00, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Le 15/02/2016 07:51, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Hi Joaquin,
I have a use case where I have several keys to the same flyweight. [...]
Let say you are writing an application that manage with some entities. You have two kind of operator that use a specific protocol and each protocol identify these entities using a key MOi. Suppose that you application use a library that has an interface that use different keys to identify these same entities, because it is using an internal protocol. You want also to have some CLI for debugging purposes that uses strings to identify these same entities.
All these keys are isomorphic so you can move from one key to the other using a specific algorithm[...] OK, let's sketch these ideas. Let's say
<snip>
All of this allows us to do
int main() { multi_flyweight f1{124}; multi_flyweight f2{char{124}}; multi_flyweight f3{f2.get()}; multi_flyweight f4{f1};
std::cout<
with output
key2_from_key1 value_from_key1 124 124 124 124 1 1 1
which effectively shows that key and value creation is minimized, and the resulting semantics is what we were after. You can play with a complete example at
http://coliru.stacked-crooked.com/a/6dab2c556433fb03
Does this approach your use case? Form the functional point of view, yes, this is what I want. However we need a generic class and ensure that the size is really fly weight. Some points:
* This can be easily generalized to N keys with some metaprogramming. I believe even for 2 key we will need some meta-programming. * Note that we haven't changed the internals of Boost.Flyweight to use something like a multi-key factory (which is probably what you had in mind). Instead, this is all done on top of the existing library, which has the obvious drawback (among others) that sizeof(multi_flyweight)==2*sizeof(void*), where sizeof(flyweight) is typically sizeof(void*). Whether this is acceptable or not depends really on the use cases, I'd say. No, I want really a fly weight. If I have N key the multi_flyweight will not be fly weight anymore.
sizeof(multi_flyweight)==N*sizeof(void*)
* Rewriting this in the most efficient way through multi-key factories (likely based on Boost.MultiIndex) can be done but requires introducing whole new concepts into the framework --current factories are by definition one-key, so they simply can't be used for this. Agreed. Maybe, we can have a separated multi_flyweight class that takes care of this additional case. I see that the implementation is already using multi-index ;-) * Is this a desireable extension to Boost.Flyweight? I don't have a strong opinion myself, others' most welcome. I have no problem if this is in another library or class. What interest me is the functionality with the best performances in space and time. * Is this a good candidate for GSoC? If the answer to the above is yes, I'd say this is certainly in the good ambition/impact ratio window for a GSoC project, and I'd be happy to mentor. Glad to hear that. I believe this makes a good GSoC project. I could help you if needed. Do you mind to add an entry on the wiki https://svn.boost.org/trac/boost/wiki/SoC2016?
Best, Vicente
Vicente J. Botet Escriba
Le 16/02/2016 16:00, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Le 15/02/2016 07:51, Joaquin M LópezMuñoz a écrit :
http://coliru.stacked-crooked.com/a/6dab2c556433fb03
[...]
* [...] the obvious drawback (among others) that sizeof(multi_flyweight)==2*sizeof(void*), where sizeof(flyweight) is typically sizeof(void*). Whether this is acceptable or not depends really on the use cases, I'd say.
No, I want really a fly weight. If I have N key the multi_flyweight will not be fly weight anymore.
sizeof(multi_flyweight)==N*sizeof(void*)
No, this is not the case. sizeof(multi_flyweight)==2*sizeof(void*) for every N. The extra word is Boost.Variant's book-keeping data for type determination (internal member which_).
* Is this a desireable extension to Boost.Flyweight? I don't have a strong opinion myself, others' most welcome.
I have no problem if this is in another library or class. What interest me is the functionality with the best performances in space and time.
It'd be great if we can gauge potential interest besides your own.
* Is this a good candidate for GSoC? If the answer to the above is yes, I'd say this is certainly in the good ambition/impact ratio window for a GSoC project, and I'd be happy to mentor.
Glad to hear that. I believe this makes a good GSoC project. I could help you if needed. Do you mind to add an entry on the wiki https://svn.boost.org/trac/boost/wiki/SoC2016?
With pleasure. What's the deadline for this? Joaquín M López Muñoz Telefónica
On 17 Feb 2016 at 7:11, Joaquin M LópezMuñoz wrote:
Glad to hear that. I believe this makes a good GSoC project. I could help you if needed. Do you mind to add an entry on the wiki https://svn.boost.org/trac/boost/wiki/SoC2016?
With pleasure. What's the deadline for this?
Please get the proposal onto the wiki page above by Friday 19th at the latest. If you can we move up a category in confirmed mentors in our application, a big win. Niall --- Boost C++ Libraries Google Summer of Code 2016 admin https://svn.boost.org/trac/boost/wiki/SoC2016
Le 17/02/2016 08:11, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Le 16/02/2016 16:00, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Le 15/02/2016 07:51, Joaquin M LópezMuñoz a écrit : http://coliru.stacked-crooked.com/a/6dab2c556433fb03
[...]
* [...] the obvious drawback (among others) that sizeof(multi_flyweight)==2*sizeof(void*), where sizeof(flyweight) is typically sizeof(void*). Whether this is acceptable or not depends really on the use cases, I'd say. No, I want really a fly weight. If I have N key the multi_flyweight will not be fly weight anymore.
sizeof(multi_flyweight)==N*sizeof(void*) No, this is not the case. sizeof(multi_flyweight)==2*sizeof(void*) for every N. The extra word is Boost.Variant's book-keeping data for type determination (internal member which_).
My bad. I did a diagonal read of the code. This is already better. I believe that I could live with that even if I would prefer to spent only one pointer :)
* Is this a desireable extension to Boost.Flyweight? I don't have a strong opinion myself, others' most welcome. I have no problem if this is in another library or class. What interest me is the functionality with the best performances in space and time. It'd be great if we can gauge potential interest besides your own. You are right, if there is not interest we will lost a possible GSoC student.
Vicente
Vicente J. Botet Escriba
Do you mind to add an entry on the wiki https://svn.boost.org/trac/boost/wiki/SoC2016?
Done, please take a look at "5. Boost.Flyweight: multi-key flyweights", comments welcome. I have the feeling this is going to be quite hard, but maybe we find someone up to the task. Joaquín M López Muñoz Telefónica
Le 18/02/2016 16:20, Joaquin M LópezMuñoz a écrit :
Vicente J. Botet Escriba
writes: Do you mind to add an entry on the wiki https://svn.boost.org/trac/boost/wiki/SoC2016? Done, please take a look at "5. Boost.Flyweight: multi-key flyweights", comments welcome. I have the feeling this is going to be quite hard, but maybe we find someone up to the task.
Thanks Joaquin, it seems quite good already ;-) Vicente
participants (3)
-
Joaquin M López Muñoz
-
Niall Douglas
-
Vicente J. Botet Escriba