<div class="gmail_quote">On Thu, Jul 12, 2012 at 2:15 AM, Sanne Grinovero <span dir="ltr">&lt;<a href="mailto:sanne@hibernate.org" target="_blank">sanne@hibernate.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On 10 July 2012 12:48, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt; On Tue, Jul 10, 2012 at 2:15 PM, Galder Zamarreño &lt;<a href="mailto:galder@redhat.com">galder@redhat.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Jul 9, 2012, at 9:52 AM, Mircea Markus wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; On 06/07/2012 22:48, Sanne Grinovero wrote:<br>
&gt;&gt; &gt;&gt; On 6 July 2012 15:06, Galder Zamarreño &lt;<a href="mailto:galder@redhat.com">galder@redhat.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt;&gt; On Jun 26, 2012, at 6:13 PM, Sanne Grinovero wrote:<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; Imagine I have a value object which needs to be stored in Infinispan:<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; class Person {<br>
&gt;&gt; &gt;&gt;&gt;&gt;   final String nationality = ...<br>
&gt;&gt; &gt;&gt;&gt;&gt;   final String fullName = ...<br>
&gt;&gt; &gt;&gt;&gt;&gt; [constructor]<br>
&gt;&gt; &gt;&gt;&gt;&gt; }<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; And now let&#39;s assume that - as you could expect - most Person<br>
&gt;&gt; &gt;&gt;&gt;&gt; instances have the same value for the nationality String, but a<br>
&gt;&gt; &gt;&gt;&gt;&gt; different name.<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; I want to define a custom Externalizer for my type, but the current<br>
&gt;&gt; &gt;&gt;&gt;&gt; Externalizer API doesn&#39;t allow to refer to some common application<br>
&gt;&gt; &gt;&gt;&gt;&gt; context, which might be extremely useful to deserialize this Person<br>
&gt;&gt; &gt;&gt;&gt;&gt; instance:<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; we could avoid filling the memory of my Grid by having multiple<br>
&gt;&gt; &gt;&gt;&gt;&gt; copies<br>
&gt;&gt; &gt;&gt;&gt;&gt; of the nationality String repeated all over, when a String [1] could<br>
&gt;&gt; &gt;&gt;&gt;&gt; be reused.<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; Would it be a good idea to have the Externalizer instances have an<br>
&gt;&gt; &gt;&gt;&gt;&gt; initialization phase receiving a ComponentRegistry, so I could look<br>
&gt;&gt; &gt;&gt;&gt;&gt; up<br>
&gt;&gt; &gt;&gt;&gt;&gt; some custom service to de-duplicate or otherwise optimize my<br>
&gt;&gt; &gt;&gt;&gt;&gt; in-memory<br>
&gt;&gt; &gt;&gt;&gt;&gt; data representation?<br>
&gt;&gt; &gt;&gt;&gt;&gt; Personally I&#39;d prefer to receive it injected via the constructor so<br>
&gt;&gt; &gt;&gt;&gt;&gt; that I could use a final field when my custom Externalizer is<br>
&gt;&gt; &gt;&gt;&gt;&gt; constructed.<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; This is OGM related.<br>
&gt;&gt; &gt;&gt;&gt; ^ Makes sense, but only solves one part of the problem.<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; String is probably a bad example here [as you already said, due to 1],<br>
&gt;&gt; &gt;&gt;&gt; but a better example is if you have a Nationality class with country name,<br>
&gt;&gt; &gt;&gt;&gt; timezone…etc in it.<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; My point is, your suggestion works for nodes to which data is<br>
&gt;&gt; &gt;&gt;&gt; replicated to, but in the original node where you&#39;ve created 100 Person<br>
&gt;&gt; &gt;&gt;&gt; instances for Spanish nationaility, you&#39;d still potentially have 100<br>
&gt;&gt; &gt;&gt;&gt; instances.<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; Did you have anything in mind for this?<br>
&gt;&gt; &gt;&gt; That&#39;s where the ComponentRegistry&#39;s role kicks in: the user<br>
&gt;&gt; &gt;&gt; application created these object instances before storing them in the<br>
&gt;&gt; &gt;&gt; original node, and if it is a bit cleverly designed it will have<br>
&gt;&gt; &gt;&gt; something like a Map of immutable Nationality instances, so that every<br>
&gt;&gt; &gt;&gt; time it needs Spanish it looks up the same instance.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Consequentially the custom externalizer implementation needs access to<br>
&gt;&gt; &gt;&gt; the same service instance as used by the application, so that it can<br>
&gt;&gt; &gt;&gt; make use of the same pool rather than having to create his own pool<br>
&gt;&gt; &gt;&gt; instance: the essence of my proposal is really to have the user<br>
&gt;&gt; &gt;&gt; application and the Externalizer framework to share the same Factory.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; Btw, not sure about the need of ComponentRegistry here. IMO, this kind<br>
&gt;&gt; &gt;&gt;&gt; of feature should work for Hot Rod clients too, where Externalizers might be<br>
&gt;&gt; &gt;&gt;&gt; used in the future, and where there&#39;s no ComponentRegistry (unless it&#39;s a<br>
&gt;&gt; &gt;&gt;&gt; RemoteCacheStore...)<br>
&gt;&gt; &gt;&gt; It doesn&#39;t need to be literally a ComponentRegistry interface<br>
&gt;&gt; &gt;&gt; implementation, just anything which allows the Externalizer to be<br>
&gt;&gt; &gt;&gt; initialized using some externally provided service as in the above<br>
&gt;&gt; &gt;&gt; example.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; This optimisation should have no functional impact but just an<br>
&gt;&gt; &gt;&gt; optionally implementable trick which saves some memory.. so if we can<br>
&gt;&gt; &gt;&gt; think of a way to do the same for Hot Rod that&#39;s very cool but doesn&#39;t<br>
&gt;&gt; &gt;&gt; necessarily have to use the same components and (internal) interfaces.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I&#39;m thinking of this as a similar &quot;optionality&quot; as we have when<br>
&gt;&gt; &gt;&gt; choosing between Serializable vs. custom Externalizers : people can<br>
&gt;&gt; &gt;&gt; plug one in if they know what they&#39;re doing (like these instances<br>
&gt;&gt; &gt;&gt; should definitely be immutable) but everything just works fine if you<br>
&gt;&gt; &gt;&gt; don&#39;t.<br>
&gt;&gt; &gt;&gt; I&#39;m not really sure if there is a wide range of applications, nor have<br>
&gt;&gt; &gt;&gt; any idea of the amount of memory it could save in practice... just and<br>
&gt;&gt; &gt;&gt; idea I wanted to sketch.<br>
&gt;&gt; &gt; I think there might be quite useful; the flyweight pattern[1] was<br>
&gt;&gt; &gt; created to solve exactly this kind of *existing* problems.<br>
&gt;&gt; &gt; Just as a note, there is a simple, not necessarily nice, workaround for<br>
&gt;&gt; &gt; this: make the object pool statically accessible (or even better Enums).<br>
&gt;&gt;<br>
&gt;&gt; It&#39;s wise to avoid static object pools, cos they can lead to classloader<br>
&gt;&gt; leak issues. Enums might be better...<br>
&gt;&gt;<br>
&gt;<br>
&gt; Sanne already mentioned in another email that OGM doesn&#39;t know the actual<br>
&gt; data type at compile time, so switching to an enum is definitely not an<br>
&gt; option.<br>
<br>
</div></div>+1, thanks.<br>
<div class="im"><br>
&gt; Although it might work well enough when you know the fields ahead of time, a<br>
&gt; single static cache does seem a bit simplistic for the general case. I think<br>
&gt; in general you&#39;d want a cache per field, e.g. so that you can give up on<br>
&gt; caching once there are too many different values for that field.<br>
<br>
</div>Not sure what you mean by fields. I&#39;m not intending to specify how<br>
such a component would need to be designed, what I&#39;d like is to be<br>
able to access my application-provided services from a custom<br>
Externalizer implementation. I would then be able to do something<br>
clever, but leaving clever details to what is most suited for the<br>
application, so I don&#39;t think Infinispan should try enforce any logic,<br>
just expose the integration points.<br>
<br></blockquote><div><br>I meant a regular Java field, since that&#39;s what the Externalizer deals with. But what I had in mind was a generic Externalizer for user-supplied classes (registered at runtime), so the externalizer would need get the field metadata from a central registry and based on the current conditions it would decide whether to cache the deserialized value or not.<br>
<br>I think we all agree that Infinispan should not be concerned about how exactly this will be implemented. The discussion seems to be around whether there really is a need for such a smarter externalizer.<br><br> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
To talk specifics, I wouldn&#39;t do this per user-type fields: as you say<br>
I might have too many, my &quot;cache&quot; would need complex eviction logic.<br>
But I know that some specific fields are all very likely the same;<br>
think at &quot;table name&quot; for example, when storing the field &quot;to which<br>
table name this entry is related to&quot;, as column names and relation<br>
roles.. so not the values, but still a good boost and likely more than<br>
halving the memory overhead as for each entry we have more meta-data<br>
stuff than actual user values.<br>
<br></blockquote><div><br>The table name example isn&#39;t convincing enough, I think String.intern() would actually be a great fit here as you don&#39;t really need eviction :)<br><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

&gt;&gt; &gt; [1] <a href="http://en.wikipedia.org/wiki/Flyweight_pattern" target="_blank">http://en.wikipedia.org/wiki/Flyweight_pattern</a><br>
<br>
Exactly.<br>
<div class="im HOEnZb"><br>
&gt;&gt; &gt;&gt; I suspect it might allow me to do some cool things with both OGM and<br>
&gt;&gt; &gt;&gt; Lucene Directoy, as you can re-hidratate complex object graphs from<br>
&gt;&gt; &gt;&gt; different cache entries, reassembling them with direct references...<br>
&gt;&gt; &gt;&gt; dreaming?<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; Cheers,<br>
&gt;&gt; &gt;&gt;&gt;&gt; Sanne<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; 1 - or any immutable object: I&#39;m using String as an example so let&#39;s<br>
&gt;&gt; &gt;&gt;&gt;&gt; forget about the static String pool optimizations the JVM might<br>
&gt;&gt; &gt;&gt;&gt;&gt; enable..<br>
&gt;<br></div></blockquote></div>