[swift-users] Problem with COW optimization

Dave Abrahams dabrahams at apple.com
Sun Sep 18 22:47:30 CDT 2016

on Sun Sep 18 2016, Adrian Zubarev <swift-users-AT-swift.org> wrote:

> Dear Swift community,
> currently I’m building a value type XML library which is baked behind
> the scene with a reference type to manage graph traversing between
> nodes. I also like to COW optimize the xml graph, but I run into one
> single problem atm.
> Image this xml tree:
> <root>
>     <item/>
> </root>
> It’s just a root element with one single child. As for value types it
> should be totally fine to do something like this:
> // The given xml tree
> var root = XML.Element(name: "root")
> let item = XML.Element(name: "item")
> root.add(item)
> // The problematic behavior
> root.add(root)
> If this would be a simple value type without any references behind the
> scenes you could imagine that the result of the last code line will
> look like this:
> <root>
>     <item/>
>     <root>
>         <item/>
>     </root>
> </root>

Yep, that's exactly the right answer for a tree with value semantics.
The simplest way to implement this tree is to use an Array for the child

> Basically we copied the whole tree and added it as the second child
> into the original root element.
> As for COW optimization this is a problem, just because the passed
> root is a copy of a struct that contains the exact same reference as
> the original root element. 

I don't understand why that's a problem.

> isKnownUniquelyReferenced(&self.reference) will result in false inside
> the add method.

...as it should.

> Is there any chance I could force my program to decrease the reference
> counter of that last item after I’m sure I don’t need it?!

Which last item?  When are you sure you don't need it?  What result do
you hope for?

> A few more details: inside the add method I’m always cloning the
> passed reference just because graphs aren’t that trivial and otherwise
> I could possibly end up with a cycle graph, which would be really
> bad. After that job I’m sure that I don’t need the passed reference
> anymore and I need a way to escape from it.
> I’d appreciate any suggestions and help. :)

It's not clear what you want to acheive nor can I picture the code
you're using to acheive it, so it's hard to give useful feedback.



More information about the swift-users mailing list