[swift-users] Problem with mutable views and COW
Zhao Xin
owenzx at gmail.com
Fri Nov 18 09:21:44 CST 2016
Sorry. If you are doing something on implementing proposals, you should use
[swift-dev] list instead. Yes. I do don't know what the COW means.
Zhaoxin
On Fri, Nov 18, 2016 at 11:09 PM, Adrian Zubarev <
adrian.zubarev at devandartist.com> wrote:
> I’m sorry but you seem not to understand what I’m asking for!
>
> If you don’t know what a mutable view is, please read this proposal to
> get the basic idea: https://github.com/natecook1000/swift-evolution/
> blob/nc-dictionary-collections/proposals/0000-dictionary-key-and-value-
> collections.md
>
> Your answer doesn’t make any sense.
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 18. November 2016 um 16:05:25, Zhao Xin (owenzx at gmail.com) schrieb:
>
> protocol Copyable {
>
> func copy() -> Self
>
> }
>
>
> final class Storage:Copyable {
>
>
>
> var keys: [String] = []
>
> var values: [Int] = []
>
>
>
> func copy() -> Storage {
>
> let s = Storage()
>
> s.keys = keys
>
> s.values = values
>
>
>
> return s
>
> }
>
> }
>
>
> public struct Document:Copyable {
>
>
>
> var _storageReference: Storage
>
>
>
> public init() {
>
>
>
> self._storageReference = Storage()
>
> }
>
>
>
> public init(_ values: DocumentValues) {
>
>
>
> self._storageReference = values._storageReference
>
> }
>
>
>
> public var values: DocumentValues {
>
>
>
> get { return DocumentValues(self) }
>
>
>
> set { self = Document(newValue) }
>
> }
>
>
>
> public func copy() -> Document {
>
> var d = Document()
>
> d._storageReference = _storageReference.copy()
>
>
>
> return d
>
> }
>
> }
>
>
> var document = Document()
>
>
> let copy = document.copy()
>
>
> // just assume we already added some values and can mutate safely on a
> given index
>
> // mutation in place
>
> document.values[0] = 10 // <--- this will only mutate `document` but not
> `copy`
>
>
> You use `class` property inside `struct`, so the `struct` is no longer
> copyable. You have to do it yourself.
>
>
> Zhaoxin
>
> On Fri, Nov 18, 2016 at 10:09 PM, Adrian Zubarev <
> adrian.zubarev at devandartist.com> wrote:
>
>> Ups sorry for CCing the post to the evolution list. That happens from
>> time to time. :/
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> Am 18. November 2016 um 15:07:43, Adrian Zubarev (
>> adrian.zubarev at devandartist.com) schrieb:
>>
>> I apologize about the weak/unowned issue I mentioned. I kinda missed
>> that portion from the docs Weak references do not affect the result of
>> this function..
>>
>> Okay it’s clear to me now why the result is evaluated as false.
>>
>> But how do I solve the COW problem for mutable views?
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> Am 18. November 2016 um 15:04:55, Adrian Zubarev (
>> adrian.zubarev at devandartist.com) schrieb:
>>
>> This doesn’t make any sense.
>>
>> Somewhere from the Swift book:
>>
>> Weak and unowned references enable one instance in a reference cycle to
>> refer to the other instance *without keeping a strong hold on it*. The
>> instances can then refer to each other without creating a strong reference
>> cycle.
>>
>> From the sdlib of the function isKnownUniquelyReferenced:
>>
>> Returns a Boolean value indicating whether the given object is a class
>> instance known to have *a single strong reference*.
>>
>> unowned doesn’t increase the reference count, so the view in the
>> examples I showed should have no strong reference to that class instance.
>> The only strong reference that exists is from Document. So why exactly
>> is the result of the second isKnownUniquelyReferenced call false again?
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> Am 18. November 2016 um 14:50:57, Zhao Xin (owenzx at gmail.com) schrieb:
>>
>> >Why is the second check false, even if the property is marked as unowned for
>> the view?
>>
>> Please search the mailing list, this is not the first time it comes as a
>> new question. Shortly speaking, it is `false` only because you used
>> `unowned`. If you you can grantee it always exists. Just use it directly,
>> this is what `unowned` for. If you can't grantee that. You should use
>> `weak` and check it with `if let` or `if foo == nil`
>>
>> Zhaoxin
>>
>>
>> On Fri, Nov 18, 2016 at 8:05 PM, Adrian Zubarev via swift-users <
>> swift-users at swift.org> wrote:
>>
>>> Hi there,
>>>
>>> I just can’t get my head around mutable views and COW.
>>>
>>> Here is a small example:
>>>
>>> final class Storage {
>>>
>>> var keys: [String] = []
>>> var values: [Int] = []
>>> }
>>>
>>> public struct Document {
>>>
>>> var _storageReference: Storage
>>>
>>> public init() {
>>>
>>> self._storageReference = Storage()
>>> }
>>>
>>> public init(_ values: DocumentValues) {
>>>
>>> self._storageReference = values._storageReference
>>> }
>>>
>>> public var values: DocumentValues {
>>>
>>> get { return DocumentValues(self) }
>>>
>>> set { self = Document(newValue) }
>>> }
>>> }
>>>
>>> public struct DocumentValues : MutableCollection {
>>>
>>> unowned var _storageReference: Storage
>>>
>>> init(_ document: Document) {
>>>
>>> self._storageReference = document._storageReference
>>> }
>>>
>>> public var startIndex: Int {
>>>
>>> return self._storageReference.keys.startIndex
>>> }
>>>
>>> public var endIndex: Int {
>>>
>>> return self._storageReference.keys.endIndex
>>> }
>>>
>>> public func index(after i: Int) -> Int {
>>>
>>> return self._storageReference.keys.index(after: i)
>>> }
>>>
>>> public subscript(position: Int) -> Int {
>>>
>>> get { return _storageReference.values[position] }
>>>
>>> set { self._storageReference.values[position] = newValue } // That will break COW
>>> }
>>> }
>>>
>>> First of all the _storageReference property is unowned because I wanted
>>> to check the following:
>>>
>>> var document = Document()
>>>
>>> print(CFGetRetainCount(document._storageReference)) //=> 2
>>> print(isKnownUniquelyReferenced(&document._storageReference)) // true
>>>
>>> var values = document.values
>>>
>>> print(CFGetRetainCount(values._storageReference)) //=> 2
>>> print(isKnownUniquelyReferenced(&values._storageReference)) // false
>>>
>>> Why is the second check false, even if the property is marked as unowned
>>> for the view?
>>>
>>> Next up, I don’t have an idea how to correctly COW optimize this view.
>>> Assume the following scenario:
>>>
>>> Scenario A:
>>>
>>> var document = Document()
>>>
>>> // just assume we already added some values and can mutate safely on a given index
>>> // mutation in place
>>> document.values[0] = 10
>>>
>>> VS:
>>>
>>> Scenario B:
>>>
>>> var document = Document()
>>>
>>> let copy = document
>>>
>>> // just assume we already added some values and can mutate safely on a given index
>>> // mutation in place
>>> document.values[0] = 10 // <--- this should only mutate `document` but not `copy`
>>>
>>> We could change the subscript setter on the mutable view like this:
>>>
>>> set {
>>>
>>> if !isKnownUniquelyReferenced(&self._storageReference) {
>>>
>>> self._storageReference = ... // clone
>>> }
>>> self._storageReference.values[position] = newValue
>>> }
>>>
>>> There is only one problem here. We’d end up cloning the storage every
>>> time, because as shown in the very first example, even with unowned the
>>> function isKnownUniquelyReferenced will return false for scenario A.
>>>
>>> Any suggestions?
>>>
>>> PS: In general I also wouldn’t want to use unowned because the view
>>> should be able to outlive it’s parent.
>>>
>>>
>>> --
>>> Adrian Zubarev
>>> Sent with Airmail
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161118/071f77ca/attachment.html>
More information about the swift-users
mailing list