On Sat, 01 Oct 2011 07:18:59 -0400, Jacob Carlborg <d...@me.com> wrote:
On 2011-10-01 06:29, Robert Jacques wrote:
On Thu, 29 Sep 2011 14:58:30 -0400, Jacob Carlborg <d...@me.com> wrote:

[snip]

(2)
orange.serialization.archives.XmlArchive need to be documented.

I was hoping the Archive interface and the Base abstract class would be
enough.

For the pre-review its okay. But you'll need it for the actual review.

(3)
if Archive.Array (which is poorly named btw) "is a type independent
representation of an array" then why does it contain an elementSize field?

Suggestions for other names are welcome. Perhaps it was poorly worded,
but what I mean is that this type can represent all array types.

(3a)
Also by the time archiving is called, isSliceOf should always return
false.

Why is that?

If isSliceOf can return true, then that means that the archive is responsible 
for alias detection, management, etc. That means that every single archive 
format must implement an alias resolution algorithm. This results in a lot of 
copy/paste boiler plate which has to be maintained. It also makes it more 
difficult to get extra formats supported. Worse if someone forgets to either 
include this functionality or to apply a patch, silent bugs and/or slowdowns 
are introduced. All and archiver should be responsible for is taking some 
decorated data structure and converting it to XML/JSON/YAML/etc and back again. 
Anything more complex than that should be shared functionality located in the 
serializer / de-serializer objects.

That this function exists speaks to design problems both large
and small. On the small scale, isSliceOf indicates that you are testing
every array against every other array for slicing, which I hope is not
the case.

I do. How would I otherwise discover if an array is a slice of another
array or not?

Okay, first some rational. Consider:

assert(!a.isSliceOf(b));
assert(!b.isSliceOf(a));
assert( c.isSliceOf(a));
assert( c.isSliceOf(b));

and

class Foo {
        float x;
        float[3] point;
}

void main() {
        auto foo = new Foo;
        auto ptr = &foo.x;
        auto slice = point[0..2];
}

In the first case, a, b and c are all slices of a common root array, but the 
root array may not be serialized. In the second case, first you have a pointer 
to the inside of an object and second you have a slice of a static array inside 
an object, all three of which may be serialized together. My impression from 
your API (so this might not be correct) is that currently, you can't handle the 
above use cases. Even if you can, an O(N^2) algorithm is rather inefficient.

The solution, in my mind, is to think in terms of memory blocks/chucks. Every 
reference can be thought as pointing to a memory chunk defined by two pointers 
and a flag:

{
        void* head;                     // Start of the memory chunk
        void* tail;                     // End of the memory chunk
        bool  hasAliases;       // True if there are more than one reference to 
this chunk
}

For alias detection / resolution, you build a balanced tree of memory chunks, 
widening the chunk and flagging hasAliases as appropriate. Which should give 
you O(N log(N)) performance.

As an optimization, the user should be able to 'finalize' the serialization by 
pruning away all memory chunks without aliases. (i.e. a serializeAndClear 
method)

Reply via email to