making COW and ownership

Timon Gehr timon.gehr at gmx.ch
Wed Nov 21 02:15:53 PST 2012


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.





More information about the Digitalmars-d-learn mailing list