- Memory leak fixes:
OMDataStreamAccess was found not to have a destructor. The vast majority of C++ compilers auto generate non-virtual destructors for all classes that don't define a destructor.
Unfortunately many classes extend OMDataStreamAccess. Many instances of classes derived from OMDataStreamAccess are referenced by a OMDataStreamAccess pointer. Freeing such an
instance by deleting the base pointer reference leaks memory. Because the compiler generated base class destructor is non-virtual, none of the destructors of the extended
classes execute are called after it executes. So while the memory held by the base class is freed, the derived parts of the object are "sheered" and not freed, and that's a
memory leak. So the OMDataStreamAccess destructor was made virtual.
In ImplAAFTypeDefStream.cpp inside SetCallback, the call to QueryInterface increments the reference count in pvalInterface. To free pvalInterface the reference count must be
decremented once more. That call to release on pvalInterface has been added. To ensure that pvalInterface is not freed prematurely, a reference count up has been added to the
ImplAAFOMDataStreamAccess constructor, along with the corresponding reference count down in the destructor.
- Memory footprint optimizations:
To reduce the embarrassingly large memory footprint of the application (A seven fold explosion in ram size versus size on disk.) some data structures have been replaced with
more memory efficient structures. OMPropertySet used a red-black tree which is a memory intensive container. Surprisingly few of the performance advantages of a RBT were used.
Worse still, in some instances the RBT was treated like a vector and iterated over from start to end, to find an element. Therefore _set has been changed from a RBT to a vector
and a find function has been added to OMPropertySet to replace the built in find function of the red-black tree. Changing _set to a vector, not only reduces the memory
footprint, but due to the inefficiencies in the old code, it also provides a slight speed boost. One thing to note is that in the put function elements are pre-pended to the
vector via the call to the prepend function. That ordering is necessary for file integrity and it came for free, perhaps by lucky accident, in the RBT. The need for proper
ordering is now explicit in the code. The RBT to vector change has been propagated throughout OMPropertySetIterator.
To further optimize memory performance OMProperty has been modified. Previously OMProperty always allocated the _bits array. That is a huge waste of memory. Changes have been
made to make the _bits vector only allocate memory when it is needed. As part of those changes, the code was refactored, to properly hide private data. The _size and _bits
class attributes have been made private. And the public bits() function has been added to replace access to the newly private member _bits. Access to _bits has been replaced
with calls to bits(), throughout the toolkit. These changes not only reduce the memory footprint but make the code more maintainable and streamline the OMProperty API.