On 10 July 2012 12:48, Dan Berindei <
dan.berindei@gmail.com> wrote:
> On Tue, Jul 10, 2012 at 2:15 PM, Galder Zamarreño <
galder@redhat.com> wrote:
>>
>>
>> On Jul 9, 2012, at 9:52 AM, Mircea Markus wrote:
>>
>> > On 06/07/2012 22:48, Sanne Grinovero wrote:
>> >> On 6 July 2012 15:06, Galder Zamarreño <
galder@redhat.com> wrote:
>> >>> On Jun 26, 2012, at 6:13 PM, Sanne Grinovero wrote:
>> >>>
>> >>>> Imagine I have a value object which needs to be stored in Infinispan:
>> >>>>
>> >>>> class Person {
>> >>>> final String nationality = ...
>> >>>> final String fullName = ...
>> >>>> [constructor]
>> >>>> }
>> >>>>
>> >>>> And now let's assume that - as you could expect - most Person
>> >>>> instances have the same value for the nationality String, but a
>> >>>> different name.
>> >>>>
>> >>>> I want to define a custom Externalizer for my type, but the current
>> >>>> Externalizer API doesn't allow to refer to some common application
>> >>>> context, which might be extremely useful to deserialize this Person
>> >>>> instance:
>> >>>>
>> >>>> we could avoid filling the memory of my Grid by having multiple
>> >>>> copies
>> >>>> of the nationality String repeated all over, when a String [1] could
>> >>>> be reused.
>> >>>>
>> >>>> Would it be a good idea to have the Externalizer instances have an
>> >>>> initialization phase receiving a ComponentRegistry, so I could look
>> >>>> up
>> >>>> some custom service to de-duplicate or otherwise optimize my
>> >>>> in-memory
>> >>>> data representation?
>> >>>> Personally I'd prefer to receive it injected via the constructor so
>> >>>> that I could use a final field when my custom Externalizer is
>> >>>> constructed.
>> >>>>
>> >>>> This is OGM related.
>> >>> ^ Makes sense, but only solves one part of the problem.
>> >>>
>> >>> String is probably a bad example here [as you already said, due to 1],
>> >>> but a better example is if you have a Nationality class with country name,
>> >>> timezone…etc in it.
>> >>>
>> >>> My point is, your suggestion works for nodes to which data is
>> >>> replicated to, but in the original node where you've created 100 Person
>> >>> instances for Spanish nationaility, you'd still potentially have 100
>> >>> instances.
>> >>>
>> >>> Did you have anything in mind for this?
>> >> That's where the ComponentRegistry's role kicks in: the user
>> >> application created these object instances before storing them in the
>> >> original node, and if it is a bit cleverly designed it will have
>> >> something like a Map of immutable Nationality instances, so that every
>> >> time it needs Spanish it looks up the same instance.
>> >>
>> >> Consequentially the custom externalizer implementation needs access to
>> >> the same service instance as used by the application, so that it can
>> >> make use of the same pool rather than having to create his own pool
>> >> instance: the essence of my proposal is really to have the user
>> >> application and the Externalizer framework to share the same Factory.
>> >>
>> >>> Btw, not sure about the need of ComponentRegistry here. IMO, this kind
>> >>> of feature should work for Hot Rod clients too, where Externalizers might be
>> >>> used in the future, and where there's no ComponentRegistry (unless it's a
>> >>> RemoteCacheStore...)
>> >> It doesn't need to be literally a ComponentRegistry interface
>> >> implementation, just anything which allows the Externalizer to be
>> >> initialized using some externally provided service as in the above
>> >> example.
>> >>
>> >> This optimisation should have no functional impact but just an
>> >> optionally implementable trick which saves some memory.. so if we can
>> >> think of a way to do the same for Hot Rod that's very cool but doesn't
>> >> necessarily have to use the same components and (internal) interfaces.
>> >>
>> >> I'm thinking of this as a similar "optionality" as we have when
>> >> choosing between Serializable vs. custom Externalizers : people can
>> >> plug one in if they know what they're doing (like these instances
>> >> should definitely be immutable) but everything just works fine if you
>> >> don't.
>> >> I'm not really sure if there is a wide range of applications, nor have
>> >> any idea of the amount of memory it could save in practice... just and
>> >> idea I wanted to sketch.
>> > I think there might be quite useful; the flyweight pattern[1] was
>> > created to solve exactly this kind of *existing* problems.
>> > Just as a note, there is a simple, not necessarily nice, workaround for
>> > this: make the object pool statically accessible (or even better Enums).
>>
>> It's wise to avoid static object pools, cos they can lead to classloader
>> leak issues. Enums might be better...
>>
>
> Sanne already mentioned in another email that OGM doesn't know the actual
> data type at compile time, so switching to an enum is definitely not an
> option.