On 11/21/2012 05:23 AM, Era Scarecrow wrote:
I was thinking briefly and glancing over documentation regarding cluts
and non-cluts (Reference vs value types), and considering my BitArray
implementation. I was having a problem trying to solve how to avoid
duplicating it unless it actually was needed; And I've come to a
possible solution.
There are data types that must have new copies, but what if we delay
the duplicating unless it actually tries to make a change. Mind you this
won't be usable in all cases; But if we can put an ownership tag on it,
perhaps it might do a good portion of the job.
Here's a quick thrown together example of what I'm talking about.
[code]
import std.stdio;
import std.conv;
struct COWArray(T) {
COWArray *owner;
T[] data;
this(int i) {
owner = &this;
data.length = i;
}
inout(T) opIndex(int i) inout pure nothrow {
return data[i];
}
ref COWArray opIndexAssign(T value, int i) pure {
if (owner != &this) {
owner = &this;
data = data.dup;
}
data[i] = value;
return this;
}
}
unittest {
auto ca = COWArray!int(4);
writeln("\nOriginal:");
foreach(i; 0 .. 4) {
ca[i] = 10 + i;
writeln(ca);
}
auto new_ca = ca;
writeln("\nNew section: ");
foreach(i; 0 .. 4) {
new_ca[i] = 200 + i;
writeln(new_ca);
}
writeln("\nPost processing:");
writeln(ca);
writeln(new_ca);
}
[/code]
This produces:
Original:
COWArray!(int)(18FDCC, [10, 0, 0, 0])
COWArray!(int)(18FDCC, [10, 11, 0, 0])
COWArray!(int)(18FDCC, [10, 11, 12, 0])
COWArray!(int)(18FDCC, [10, 11, 12, 13])
New section:
COWArray!(int)(18FDE4, [200, 11, 12, 13])
COWArray!(int)(18FDE4, [200, 201, 12, 13])
COWArray!(int)(18FDE4, [200, 201, 202, 13])
COWArray!(int)(18FDE4, [200, 201, 202, 203])
Post processing:
COWArray!(int)(18FDCC, [10, 11, 12, 13])
COWArray!(int)(18FDE4, [200, 201, 202, 203])
This also duplicates the data if you move the struct in memory and then
mutate. Probably you just need to have a boolean owner flag and set it
to false on postblit.