Transfers the data into a new item-list. The size of the new item-list must equal newItemCount()
| 289 | |
| 290 | ///Transfers the data into a new item-list. The size of the new item-list must equal newItemCount() |
| 291 | void transferData(Data* newItems, uint newCount, int* newCentralFree = nullptr) |
| 292 | { |
| 293 | DEBUG_FREEITEM_COUNT |
| 294 | |
| 295 | uint currentRealCount = m_itemCount - countFreeItems(*m_centralFreeItem); |
| 296 | // Q_ASSERT(currentRealCount + (currentRealCount/increaseFraction) == newCount); |
| 297 | |
| 298 | //Create a new list where the items from m_items are put into newItems, with the free items evenly |
| 299 | //distributed, and a clean balanced free-tree. |
| 300 | uint newFreeCount = newCount - currentRealCount; |
| 301 | uint freeItemRaster; |
| 302 | if (newFreeCount) |
| 303 | freeItemRaster = newCount / newFreeCount; |
| 304 | else { |
| 305 | freeItemRaster = newCount + 1; //No free items |
| 306 | } |
| 307 | |
| 308 | ///@todo Do not iterate through all items, instead use the free-tree and memcpy for the ranges between free items. |
| 309 | ///Ideally, even the free-tree would be built on-the-fly. |
| 310 | Q_ASSERT(freeItemRaster); |
| 311 | uint offset = 0; |
| 312 | uint insertedValidCount = 0; |
| 313 | for (uint a = 0; a < newCount; ++a) { |
| 314 | //Create new free items at the end of their raster range |
| 315 | if (a % freeItemRaster == (freeItemRaster - 1)) { |
| 316 | //We need to insert a free item |
| 317 | ItemHandler::createFreeItem(newItems[a]); |
| 318 | ++offset; |
| 319 | } else { |
| 320 | ++insertedValidCount; |
| 321 | while (ItemHandler::isFree(m_items[a - offset]) && a - offset < m_itemCount) |
| 322 | --offset; |
| 323 | Q_ASSERT(a - offset < m_itemCount); |
| 324 | newItems[a] = m_items[a - offset]; |
| 325 | // Q_ASSERT(!ItemHandler::isFree(newItems[a])); |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | Q_ASSERT(insertedValidCount == m_itemCount - countFreeItems(*m_centralFreeItem)); |
| 330 | // qCDebug(UTIL) << m_itemCount << newCount << offset; |
| 331 | // Q_ASSERT(m_itemCount == newCount-offset); |
| 332 | |
| 333 | m_items = newItems; |
| 334 | m_itemCount = newCount; |
| 335 | |
| 336 | if (newCentralFree) |
| 337 | m_centralFreeItem = newCentralFree; |
| 338 | |
| 339 | *m_centralFreeItem = buildFreeTree(newFreeCount, freeItemRaster, freeItemRaster - 1); |
| 340 | |
| 341 | // qCDebug(UTIL) << "count of new free items:" << newFreeCount; |
| 342 | |
| 343 | // Q_ASSERT(countFreeItems( *m_centralFreeItem ) == newFreeCount); |
| 344 | |
| 345 | DEBUG_FREEITEM_COUNT |
| 346 | } |
| 347 | |
| 348 | ///Tries to put the item into the list. If the insertion would be too inefficient or is not possible, returns false, unless @param force is true |
no outgoing calls