A Refcounted Array Type

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 24 14:27:40 PST 2015


On Monday, 23 February 2015 at 22:15:54 UTC, Walter Bright wrote:
> struct RCArray(E) {
>
>     this(E[] a)
>     {
>         array = a.dup;
>         start = 0;
>         end = a.length;
>         count = new int;
>         *count = 1;
>     }
>

This may not be @safe depending on the type of E. Also, this do 
not really solve the garbage problem

>     ~this()
>     {
>         if (count && --*count == 0)
>             delete array;
>     }
>
>     this(this)
>     {
>         if (count)
>             ++*count;
>     }
>

Here, we are going to run a bunch of null check because we can't 
enforce proper construction of struct. This is not per se a 
limitation of this piece of code, simply a long standing issue 
that should up.

Also, there are no way to ensure that the array is going to be 
bound to one thread, even without shared (exception, delegate, 
destructor, pure return). You need at least atomic increment 
and/or decrement.

But worse, as this can be assigned to static variables, you need 
to lock the whole damn struct unless you can update it 
atomically. The struct is 320 bits large and it is not updatable 
atomically in any arch I know of.

You need a mutex.

>     size_t length()
>     {
>         return end - start;
>     }
>
>     ref E opIndex(size_t i) return // here's the magic
>     {
>         return array[start + i];
>     }
>

I have to admit, that is pretty cool. But it is only gonna work 
with value types.

>     RCArray opSlice(size_t lwr, size_t upr)
>     {
>         RCArray result = this;
>         result.start = start + lwr;
>         result.end = start + upr;
>         return result;
>     }
>

You need bound check: end <= start <= array.length .

>   private:
>     E[] array;
>     size_t start, end;
>     int* count;
> }
>



More information about the Digitalmars-d mailing list