diff -r 11d3954df52a -r 627c4a0fd0e7 src/hbtools/hbbincssmaker/hbcssconverterutils.cpp --- a/src/hbtools/hbbincssmaker/hbcssconverterutils.cpp Thu May 27 13:10:59 2010 +0300 +++ b/src/hbtools/hbbincssmaker/hbcssconverterutils.cpp Fri Jun 11 13:58:22 2010 +0300 @@ -55,10 +55,16 @@ registered.remove(offset); } - -QList HbCssConverterUtils::registeredOffsetHolders() +QMultiHash HbCssConverterUtils::registeredOffsetHolders() { - return registered.keys(); + QMultiHash holders; + holders.reserve(registered.size()); + QMap::const_iterator end = registered.constEnd(); + for (QMap::const_iterator i = registered.constBegin(); i != end; ++i) { + int *holder = i.key(); + holders.insertMulti(*holder, holder); + } + return holders; } void HbCssConverterUtils::unregisterAll() @@ -84,13 +90,14 @@ GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory); HbSharedMemoryManager *shared = static_cast(manager); const char *chunkBase = static_cast(shared->base()); + const char *freedEnd = chunkBase + offset + size; + const int *freedStart = reinterpret_cast(chunkBase + offset); - QList offsetHolders = HbCssConverterUtils::registeredOffsetHolders(); - for (int i = 0; i= chunkBase + offset && (char*)holder < chunkBase + offset + size) { - HbCssConverterUtils::unregisterOffsetHolder(holder); - } + QMap::iterator freedHolders = + registered.lowerBound(const_cast(freedStart)); + while(freedHolders != registered.end() + && reinterpret_cast(freedHolders.key()) < freedEnd) { + freedHolders = registered.erase(freedHolders); } } } @@ -102,19 +109,23 @@ if (size > 0) { // Check if there were registered offset holders in the old cell // and register corresponding ones in the reallocated cell. - QList holders = HbCssConverterUtils::registeredOffsetHolders(); - GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory); HbSharedMemoryManager *shared = static_cast(manager); - const char *chunkBase = static_cast(shared->base()); - - for (int i=0; i= chunkBase + offset && holderC < chunkBase + offset + size) { - HbCssConverterUtils::unregisterOffsetHolder(holder); - HbCssConverterUtils::registerOffsetHolder((int*)(holderC + newOffset - offset)); - } + const char *chunkBase = static_cast(shared->base()); + const char *freedEnd = chunkBase + offset + size; + const int *freedStart = reinterpret_cast(chunkBase + offset); + + QMap::iterator freedHolders = + registered.lowerBound(const_cast(freedStart)); + QList newHolders; + while(freedHolders != registered.end() + && reinterpret_cast(freedHolders.key()) < freedEnd) { + char *holderC = reinterpret_cast(freedHolders.key()); + newHolders.append(reinterpret_cast(holderC + newOffset - offset)); + freedHolders = registered.erase(freedHolders); + } + for (int i = 0; i < newHolders.size(); ++i) { + registerOffsetHolder(newHolders.at(i)); } } } @@ -129,62 +140,56 @@ GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory); HbSharedMemoryManager *shared = static_cast(manager); - // Register shared cache pointer in chunk header as shared cache may also be moved in defragmentation - HbSharedChunkHeader *chunkHeader = static_cast(shared->base()); - HbCssConverterUtils::registerOffsetHolder(reinterpret_cast(&chunkHeader->sharedCacheOffset)); + // Register shared cache pointer in chunk header + //as shared cache may also be moved in defragmentation + HbSharedChunkHeader *chunkHeader = static_cast(shared->base()); + registerOffsetHolder(reinterpret_cast(&chunkHeader->sharedCacheOffset)); - QList offsetHolders = HbCssConverterUtils::registeredOffsetHolders(); + QMultiHash offsetHolders = registeredOffsetHolders(); // Create new buffer where the current chunk contents are defragmented - void *buffer = ::malloc(shared->size()); + char *buffer = static_cast(::malloc(shared->size())); int newCurrentOffset = 0; // Create new cell order and update offset holders - QMap::const_iterator i = cells.constBegin(); + QMap::const_iterator end = cells.constEnd(); - while (i != cells.constEnd()) { + for (QMap::const_iterator i = cells.constBegin(); i != end; ++i) { // Get the old cell int offset = i.key(); int size = i.value(); // Update registered offset holders - - // TODO: optimize this, now there's linear search for each cell! - for (int j=0; j values = offsetHolders.values(offset); + offsetHolders.remove(offset); + int newOffset = newCurrentOffset + sizeof(HbSharedChunkHeader); + for (int j = 0; j < values.size(); ++j) { + int *holder = values[j]; + *holder = newOffset; + offsetHolders.insertMulti(*holder, holder); + } newCurrentOffset += size; - i++; } - i = cells.constBegin(); newCurrentOffset = 0; - // Move allocated cells to a linear buffer - while (i != cells.constEnd()) { + for (QMap::const_iterator i = cells.constBegin(); i != end; ++i) { // Get the old cell int offset = i.key(); int size = i.value(); // Copy to new chunk - memcpy((char*)buffer + newCurrentOffset, (char*)shared->base() + offset, size); - + memcpy(buffer + newCurrentOffset, static_cast(shared->base()) + offset, size); newCurrentOffset += size; - i++; } // Free all cells from the shared chunk and move the defragmented buffer in the beginning of the chunk. // Note that chunk memory management is screwed up after this point, so no more allocations should be // done in it after this. - HbCssConverterUtils::unregisterAll(); + unregisterAll(); QList keys = cells.keys(); - for (int j=0; jfree(keys.at(j)); }