Request for pre-review: std.serialization/orange

Robert Jacques sandford at jhu.edu
Tue Oct 4 08:14:12 PDT 2011


On Tue, 04 Oct 2011 03:22:35 -0400, Jacob Carlborg <doob at me.com> wrote:
> On 2011-10-04 07:21, Robert Jacques wrote:

[snip]

>>> Actually it does not need to be part of the public API when I think
>>> about it. I can move it into Serializer. Array would still need to be
>>> public since both Serailzer and Archive need access to it and the
>>> package attribute doesn't work very well.
>>
>> Regarding design, I agree, although I'd go one further and define Array
>> as a public type inside the Serializer class. However, this concept of
>> an 'Array' is fundamentally flawed. Consider:
>>
>> auto c = a[1..3];
>>
>> auto cArr = Array(c.ptr,c.length,4);
>>
>> assert(!cArr.isSliceOf(bArr));
>> assert(!bArr.isSliceOf(cArr));
>
> Any suggestion how to fix this, how to properly detect if an array is a
> slice of some other array?

Well, there are two problems. First, there is an API issue: When you pass an aliased array to the archiver, you must pass both an array and a slice of that array.
Second, is detection. The comparison operator I suggested below covers this issue. Just remember that with a loop based approach, you can't terminate the search early: you have to check all existing arrays for possible matches.

>> // and
>>
>> b ~= 5;
>>
>> bArr = Array(b.ptr, b.length, 4);
>>
>> assert(!bArr.isSliceOf(aArr));
>
> Appending to "b" will reallocate "b" making it a regular array and not a
> slice:
>
> b ~= 5;
> b[] = 100;
> assert(a == [0, 1, 2, 3, 4]);
>
> "a" is not modified and the assert passes.

I'm sorry, you're right. In my mind b extended to the end of the a array, for some reason. However, if you do define b to extend to the end of the a array, then it can append without allocating:

	auto a = [0, 1, 2, 3, 4];
	auto b = a[2 .. $];
	b ~= 5;
	assert(b[0]==2);
	a[2] = 10;
	assert(b[0]==10);

So please don't dismiss this point.

[snip]

> Would this something similar to:
> https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1520
> ?

I'm not sure, that routine seems to be filtering pointers between those with aliases and those without aliases, which would be similar in effect to:

if( auto node = arr.ptr in setOfAliases ) {} else {}

> What is the advantage with using a tree? Is the advantage that you loop
> over the elements once in the pseudo-code compared to that I loop over
> them twice, as in:
> https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1495
> ?

Primarily, it's O(N logN) vs O(N^2). Also, it solves the isSliceOf problem we discussed above and puts arrays and objects into the same framework, as objects containing fixed sized arrays can have slices.


More information about the Digitalmars-d mailing list