[EMAIL PROTECTED] wrote:
Samisa, I did think some more today about your suggestion to serialize and deserialize to accomplish a clone operation. When I first ran into this requirement to copy an axiom subtree in my application, I investigated writing something to accomplish a clone this way. While I was researching whether enough entry points were public to accomplish this in the client app, I realized that I needed more than a strict clone. I also wanted something that would let me copy the element tree without the attributes nor the text values, and something to copy the element tree with the text values but without the attributes. With a complete clone, I would then need to run the tree to remove the extra stuff I didn't need.
Thinking about the terminology, though, I realized that a clone may be exactly what some users want. The difference is that a copy, along the lines I suggest, would share the attributes. This is fine for most purposes, and is very efficient. But if the application then found an attribute and modified its value, it would modify the value in both the original and the cloned tree. Obviously the code could avoid this anomaly by deleting the attribute from the cloned tree and creating a new attribute with the new value, breaking the link between the two trees. But this would not be obvious to someone who used a method named clone.
So I'm beginning to think there should be two functions, one is a shallow copy of all the data elements and text values, sharing the attributes and namespaces, the second is a true clone of all the structures throughout the tree. And certainly you are right that the easiest way to implement clone as a deep copy is to serialize the tree and deserialize it into a new structure.
I agree with you 100%. With ref counts, what we effectively have is a
shallow copy, and that would work, as ling as the two "virtual" copies
are supposed to be identical. If in any case, one wants to modify one
tree independent of the other, then the shallow copy with ref counts
would not work, in which case you can look to the alternative of
serilizing and deserializing for a deep copy.
Thanks,
Samisa...
Kasun, do you think you really need a clone of the tree? Are you intending to
find attributes in the tree and modify their values? Are does a copy of the
tree suffice, where you could delete the attributes you don't want or add new
ones, but where modifying the value of an existing attribute might modify the
original?
Regards,
Bill
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Thursday, February 14, 2008 7:09 AM
To: axis-c-dev@ws.apache.org
Subject: RE: Issue in using 'detach' for cloning
Good, Samisa, I did explain it clearly enough. The fact that an attribute may contain a pointer to a namespace without the pointer being included in the namespace ref count strikes one at first glance as odd. But it works, if and only if, the same namespace structure is declared for one of the parent elements of the attribute. So the current design, where the attribute does not directly participate in incrementing and freeing the namespace structures can be made to work, but it's fragile. And the primary question is whether we want to keep this architecture.
If we want to keep this architecture, I see two suggestions to fixing the issue with detach without a deep clone of the namespaces. After all, cloning the namespaces would mean new structures, and all the namespace pointers in the subtree would need to be updated to the cloned values. Either we could run the subtree to ensure that every namespace pointer in the subtree that refers to a namespace declared above the subtree is declared again at the root of the subtree. Or we could just run through the parents of the root of the subtree, and for any namespaces associated with the parents re-declare them at the subtree root, taking into account that only one namespace can be in-scope for any particular prefix. Either way, declaring the namespace structure again at the subtree root will cause its ref-count to be incremented and the structure not freed until the detached subtree is freed. The second approach may cause some namespaces to be declared at the root that are never used by the subtree, but it has a simple logic of gathering up all the namespaces that are in scope at that point in the tree, and re-declaring them.
So the current architecture can be kept without too much work.
To show how it's fragile, one of the mistakes I made in trying to write a clone routine was that I determined the default namespace at the source root using axiom_element_get_default_namespace, and then used axiom_element_declare_default_namespace to declare the same namespace in the cloned root. Well, declare_default_namespace accepts a URI, not a namespace pointer, so the new cloned tree pointed to a new namespace structure for the default namespace, while attributes in the cloned subtree pointed to the original namespace structure.
We all understand ref counts and with some effort we can go through the code and make sure that every pointer to a namespace either in an element or in an attribute is included in its ref count. This would, IMHO, create a more robust structure. Implementing this is a little error prone, though, and there is some risk of getting it wrong the first time. Re-declaring all the in-scope namespaces at the detached subtree root is easier to implement, and I think is still sufficient to allow a clone algorithm to work by cloning just the elements while sharing the namespaces and attributes through their ref counts.
Regards,
Bill
-----Original Message-----
From: Samisa Abeysinghe [mailto:[EMAIL PROTECTED]
Sent: Thursday, February 14, 2008 3:54 AM
To: Apache AXIS C Developers List
Subject: Re: Issue in using 'detach' for cloning
[EMAIL PROTECTED] wrote:
...
So for a clone algorithm to work reasonably, one of two things must happen. (1) The cloned tree points to the very same namespace structures. When these are declared with the new elements, their ref counts will be incremented, and so they will not be deallocated when the original tree is freed. Or, (2) where the attributes point to a namespace structure, these pointers should be ref counted just like the pointers in the elements. In this case, even if the element in the new tree pointed to equivalent namespace values in new structures, the namespaces would not disappear under the attributes until the attributes themselves were released, because the ref counts on the namespaces would keep them around.
...
To work correctly, axiom_node _detach must meet either requirement (1) or (2) above, just like cloning. Either (1) every namespace referenced in the detached subtree but declared at a higher level must now be declared at the root of the detached tree as well, so that their ref counts will now be incremented to keep the namespaces around. Or (2) the pointers to namespaces in the attributes structures need to be included in the namespace ref counts. At least in the context of my own application, I should be able to verify this with a clever test case.
...
I think I understand your concerns as well as the issue raised by Kasun.
If we think that fixing detach would fix this problem, then we can
consider fixing detach related problems by introducing deep copy of
namespaces in case of detaching. A workaround for the time being would
be to use serialize_sub_tree on the node to be detached and then build
the OM again form the serialized string, and you have a clone of that
sub tree - not that efficient - but works - it is a hack.
However, reading your mail, I do agree with you that using ref counts
would solve the problem. It is a bit tricky to implement due to the
assumptions that we may have made in handling the ref counts right now,
but still that would be possible. At the moment, the ref counts are used
solely to help resolve memory leak problems. If we are to use ref count
for cloning, we have to ensure that the current assumptions are not
broken or fixed to live with new cloning logic.
Samisa...
Bill Mitchell
--------------------------------------------------------------------------------------------
From: Kasun Indrasiri [mailto:[EMAIL PROTECTED]
Sent: Wednesday, February 13, 2008 12:03 AM
To: Apache AXIS C Developers List
Subject: Issue in using 'detach' for cloning
Hi,
-There is an issue in axiom_node_detach function which is related to
namespaces. Once we detach a child node from a root node and then free the
allocated memory for root node, the associated namespace for the detached node
is also freed.
For e.g. If we try to axiom_node_to_string -> it prints 'null' . But we can
get any other attribute (local name or text) from the detached node.
- And also for cloning nodes, we should have a better approach than 'detach'.
Because, detach remove the node from the original node.
Thanks,
Kasun
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]