making COW and ownership
Dan
dbdavidson at yahoo.com
Wed Nov 21 07:06:34 PST 2012
On Wednesday, 21 November 2012 at 04:23:56 UTC, Era Scarecrow
wrote:
> Here's a quick thrown together example of what I'm talking
> about.
I think I see where you are going. After the copy creation of
new_ca you have two objects referencing exactly the same data. It
doesn't show it, but the benefit is that a whole bunch of reading
can be going on against two handles to the same data without
conflict (i.e. before the first assignment 'new_ca[i] = 200+i;'
and you have delayed work. I think for this to be effective or
sane you have to lock all the doors of change. So, for example,
you would need 'data' to be private, otherwise data could be
changed without successfully triggering the copy via
opAssignIndex. Also, if ca itself were changed after the
assignment to new_ca, but before mutation on new_ca got its copy
then both would see that change, which is probably not desired.
An alternative might be to use the const system. Assume that the
whole lot of reading is going on in multiple pieces of code -
different functions. Just give them the original bit array as
const. Then they can not write to it directly, but can read from
it. Eventually when they need to mutate they would need to copy
just before beginning mutation. The const system helps, but what
is missing is a way to copy a const object. No way exists yet -
but I'm proposing and have a 'gdup' that does for this case. Any
comments on it appreciated.
https://github.com/patefacio/d-help/blob/master/doc/canonical.pdf
https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d
The idea is that the transitive nature of const in D is perfect
for providing those copy on write semantics without any extra
work if you can copy the const object when needed.
Thanks
Dan
--------------------------------------------------
import std.stdio;
import std.conv;
import opmix.mix;
struct COWArray(T) {
private T[] data;
this(int i) {
data.length = i;
}
inout(T) opIndex(int i) inout pure nothrow {
return data[i];
}
ref COWArray opIndexAssign(T value, int i) pure {
data[i] = value;
return this;
}
}
void give_away_ref(T)(ref const(COWArray!T) ca) {
// Do lots of reading
auto new_ca = ca.gdup;
writeln("\nNew section: ");
foreach(i; 0 .. 4) {
new_ca[i] = 200 + i;
writeln(new_ca);
}
}
unittest {
auto ca = COWArray!int(4);
writeln("\nOriginal:");
foreach(i; 0 .. 4) {
ca[i] = 10 + i;
writeln(ca);
}
give_away_ref(ca);
writeln("\nPost processing:");
writeln(ca);
}
More information about the Digitalmars-d-learn
mailing list