just one thing.
It is not possible to really seperate changes from its page.
Because changes (mostly components) always have there parent (so you can re
attach them)
And we have no idea what the components or models also by itself have
references to the page. (anon classes)
so i don't see any real value of separating the changes from a page. Because
what would you do with that?
save only changes? But then you will save the page anyway.
The page itself will be smaller ofcourse. But with the second level cache if
we implement it right
we only really have to keep 1 page version (maybe not even that but that is
what i would do)
johan
On 2/2/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
before johan complains, i just realized there's a flaw in my little
plan. you still have to undo changes to pages that are not reconstructed
by custom IPageMapEntry implementations because the page is in the
state of the highest ordinal in the page map because that was the last
one accessed. even so, a little more logic here should correct for that.
Jonathan Locke wrote:
>
>
> A part of this whole discussion of serializing page map entries is
> also the current open bug that Eelco submitted that we should make
> page versions separate from pages. This came up over at Diva espresso
> a few minutes ago when Eelco and I were chatting and I had an
> interesting and very elegant little idea that could sort this out
> quite nicely. Not only would it definitely make things more efficient,
> it would also be a more elegant solution that fixes an unreported bug.
>
> first, i think that IPageMapEntry.getNumericId is really more like
> getOrdinal since page ids will always increment in a page map.
> but regardless, to implement a page version based on another page
> in the page map (which might also be a page version), we can use a
> simple little container implementing IPageMapEntry to hold the
> base pagemap entry id and the changes to apply to that page.
> this container might be just an anonymous class, but let's give it
> a name here for clarity:
>
> class PageVersion implements IPageMapEntry
> {
> // Identifier of page map entry to apply these changes to
> // If we're using ordinals, we don't need this field at all
> // because the page this version is based on will be our own
> // ordinal - 1.
> int basePageMapEntryNumericId;
>
> // Don't recall the exact base class name for change entries
> // in the versioning code, but this is the list of changes to apply
> List<Change> changes;
>
> Page getPage()
> {
> // Get previous page (possibly recursing)
> final Page page = pageMap.get(basePageMapEntryNumericId);
>
> // Apply changes to page
> page.applyChanges(changes();
> return page;
> }
> }
>
> this should work nicely and actually this fixes an existing bug because
> right
> now if you provide a custom implementation of IPageMapEntry to
reconstruct
> a page, that page is probably not versionable. in this case it would be
> because
> the recursion would bottom out and reconstruct that page.
>
>
> igor.vaynberg wrote:
>>
>> another idea to optimize serialization state from jon and i
>>
>> allow an easy way to override model serialization
>>
>> a simple example:
>>
>> class EntityModel extends LoadableDetachableModel {
>> private long id;
>> //standard junk
>> }
>>
>> now when this is serialized you get a bunch of junk like the class
>> header,
>> etc, but all you really care about is that single long id field. so
what
>> if
>> you have
>>
>> interface ModelSerializationCodec {
>> boolean supportsModel(Class<? extends IModel>);
>> writeModel(ObjectOutputStream s, IModel model);
>> IModel readModel(ObjectInputStream);
>> }
>>
>> class ModelSerializationCodecRegistry {
>> private ModelSerializationCodec[]=new ModelSerializationCodec[255];
>> void registerCodec(ModelSerializationCodec codec) {...}
>> void codecForId(byte id) {...}
>> int codecIdForClass(Class<? extends IModel>){...}
>> }
>>
>> Component.writeObject(ObjectOutputStream oos) {
>> // or instead of overriding component.writeobject we can put model
>> // into a model holder object that has this logic
>> // or even wrap the model in the model holder conditionally when the
>> model
>> is set only if there is a codec
>>
>> // i suppose this can also be in a special outputstream we use so it
>> doesnt
>> have to be in the component
>> // we already have a few of these
>> ...
>> // write out model
>> byte codecId=registry.codecIdForClass(model.getClass());
>> oos.writebyte(0);
>>
>> if (codecId!=0) {
>> registry.codecForId(codecId).writeModel(oos, model);
>> }
>> }
>>
>> class EntityModelCodec implements ModelSerializationCodec {
>> boolean supportsModel(Class<? extends IModel> c) { return
>> EntityModel.class.equals(c); }
>> writeModel(ObjectOutputStream s, IModel model) { s.writeLong(model.id);
}
>> IModel readModel(ObjectInputStream ois) { EntityModel em=new
>> EntityModel();
>> em.id=ois.readLong(); }}
>>
>> so now instead of serializing the entire model instance you can just
>> write
>> out the fields you need and because this ability is outside the model
you
>> can write out simple primitives. the downside is that for any model
that
>> doesnt have a codec the size of output takes an extra hit - which is
the
>> codec id byte. the question is how many bytes are in the extra junk
like
>> class header - this ratio will determine if this is generally worth
>> doing.
>>
>> the only trick here is to keep the codecid byte consistent across the
>> cluster. we can probably use initializers to do that for components
that
>> come in jars, just add a registerModelCodecs to the initializer and
also
>> allow the same from application.init()
>>
>> does this make sense? what do you guys think?
>>
>> -igor
>>
>>
>
>
--
View this message in context:
http://www.nabble.com/optimizing-serialized-state%3A-model-serialization-codecs-idea-tf3140882.html#a8775862
Sent from the Wicket - Dev mailing list archive at Nabble.com.