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#a8775808
Sent from the Wicket - Dev mailing list archive at Nabble.com.