deepCopy

Denis Koroskin 2korden at gmail.com
Mon Oct 18 15:01:05 PDT 2010


Okay, we've finished what we started with Aleksey today, so I decided to  
share it with you. This is a rough cut, it lacks comments, but it is  
already usable.

deepCopy is a function that makes a deep copy of your object, and  
everything it points to. As simple as that.

Essentially it is a binary serializer except that it doesn't store  
pointers as offsets (although it is capable of doing that, too - change a  
single line - so serialize and deepCopy share 99% of the code).

deepCopy and serialize are similar in design yet different in usage:  
serialized data are usually transmitted to other application, and one must  
worry about different endianness, pointer size etc. On the contrary  
deepCopy is to be used within the same address space and is free from such  
issues.

deepCopy is useful for making sure there are no aliases to your data left.  
This can be used to create a safe immutable copy of your objects, or to  
avoid with memory leaks.

We've written deepCopy to solve memory leaks in ddmd the following way:
a) hook all the memory allocations
b) run code, produce result
c) make a deep copy of the result
d) release all the allocated memory

Since you are deallocating all the memory at once, you can use faster  
allocation methods e.g preallocate a memory and simply advance a pointer,  
or use dsimcha's tempAlloc  
(http://dsource.org/projects/scrapple/browser/trunk/tempAlloc). BTW, I  
remember a discussion about integrating it into druntime, did it go  
anywhere since then?.

deepCopy stores all the data sequentially, so it should reduce memory  
fragmentation and should be more cache-friendly. As a downside, the whole  
block will only be release once last reference to it expires.

If your struct has pointers you can manually specify if that pointer is a  
pointer to one element (default), many or none (excluding it from being  
copied). Exclusion works with references, too:

class Foo : ISerializeable
{
     mixin Serializeable;

     // optional, only needed for precise serialization control
     void describe(SerializeInfo* info)
     {
         info.setLength(buffer, length);
         info.exclude(cachedValue);
     }

     ubyte* buffer;
     size_t length;
     Object cachedValue;
}

I hope someone will find it useful, the code with tests is located here:
http://bitbucket.org/korDen/serialize/src/tip/

Suggestions are welcome!


More information about the Digitalmars-d mailing list