TODO: OPT: this should be made much faster
| 296 | |
| 297 | // TODO: OPT: this should be made much faster |
| 298 | int CSnapshotDelta::CreateDelta(const CSnapshot *pFrom, const CSnapshot *pTo, void *pDstData) |
| 299 | { |
| 300 | CData *pDelta = (CData *)pDstData; |
| 301 | int *pData = (int *)pDelta->m_aData; |
| 302 | |
| 303 | pDelta->m_NumDeletedItems = 0; |
| 304 | pDelta->m_NumUpdateItems = 0; |
| 305 | pDelta->m_NumTempItems = 0; |
| 306 | |
| 307 | CItemList aHashlist[HASHLIST_SIZE]; |
| 308 | GenerateHash(aHashlist, pTo); |
| 309 | |
| 310 | // pack deleted stuff |
| 311 | for(int i = 0; i < pFrom->NumItems(); i++) |
| 312 | { |
| 313 | const CSnapshotItem *pFromItem = pFrom->GetItem(i); |
| 314 | if(GetItemIndexHashed(pFromItem->Key(), aHashlist) == -1) |
| 315 | { |
| 316 | // deleted |
| 317 | pDelta->m_NumDeletedItems++; |
| 318 | *pData = pFromItem->Key(); |
| 319 | pData++; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | GenerateHash(aHashlist, pFrom); |
| 324 | |
| 325 | // fetch previous indices |
| 326 | // we do this as a separate pass because it helps the cache |
| 327 | int aPastIndices[CSnapshot::MAX_ITEMS]; |
| 328 | const int NumItems = pTo->NumItems(); |
| 329 | for(int i = 0; i < NumItems; i++) |
| 330 | { |
| 331 | const CSnapshotItem *pCurItem = pTo->GetItem(i); // O(1) .. O(n) |
| 332 | aPastIndices[i] = GetItemIndexHashed(pCurItem->Key(), aHashlist); // O(n) .. O(n^n) |
| 333 | } |
| 334 | |
| 335 | for(int i = 0; i < NumItems; i++) |
| 336 | { |
| 337 | // do delta |
| 338 | const int ItemSize = pTo->GetItemSize(i); // O(1) .. O(n) |
| 339 | const CSnapshotItem *pCurItem = pTo->GetItem(i); // O(1) .. O(n) |
| 340 | const int PastIndex = aPastIndices[i]; |
| 341 | const bool IncludeSize = pCurItem->Type() >= MAX_NETOBJSIZES || !m_aItemSizes[pCurItem->Type()]; |
| 342 | |
| 343 | if(PastIndex != -1) |
| 344 | { |
| 345 | int *pItemDataDst = pData + 3; |
| 346 | |
| 347 | const CSnapshotItem *pPastItem = pFrom->GetItem(PastIndex); |
| 348 | |
| 349 | if(!IncludeSize) |
| 350 | pItemDataDst = pData + 2; |
| 351 | |
| 352 | if(DiffItem(pPastItem->Data(), pCurItem->Data(), pItemDataDst, ItemSize / sizeof(int32_t))) |
| 353 | { |
| 354 | *pData++ = pCurItem->Type(); |
| 355 | *pData++ = pCurItem->Id(); |
no test coverage detected