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.



Reply via email to