ole32: Track the lowest possibly-free small block in storage files.

This makes creating small block chains O(n) instead of O(n**2) because we
don't have to keep rechecking the first blocks in the file.
This commit is contained in:
Vincent Povirk 2010-03-20 13:13:47 -05:00 committed by Alexandre Julliard
parent ba51763f4a
commit e05b8416b8
2 changed files with 9 additions and 1 deletions

View File

@ -2711,6 +2711,8 @@ static HRESULT StorageImpl_Construct(
*/
This->prevFreeBlock = 0;
This->firstFreeSmallBlock = 0;
/*
* Create the block chain abstractions.
*/
@ -5710,7 +5712,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
ULARGE_INTEGER offsetOfBlockInDepot;
DWORD buffer;
ULONG bytesRead;
ULONG blockIndex = 0;
ULONG blockIndex = This->parentStorage->firstFreeSmallBlock;
ULONG nextBlockIndex = BLOCK_END_OF_CHAIN;
HRESULT res = S_OK;
ULONG smallBlocksPerBigBlock;
@ -5819,6 +5821,8 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
}
}
This->parentStorage->firstFreeSmallBlock = blockIndex+1;
smallBlocksPerBigBlock =
This->parentStorage->bigBlockSize / This->parentStorage->smallBlockSize;
@ -6117,6 +6121,7 @@ static BOOL SmallBlockChainStream_Shrink(
&blockIndex)))
return FALSE;
SmallBlockChainStream_FreeBlock(This, extraBlock);
This->parentStorage->firstFreeSmallBlock = min(This->parentStorage->firstFreeSmallBlock, extraBlock);
extraBlock = blockIndex;
}

View File

@ -360,6 +360,9 @@ struct StorageImpl
ULONG indexBlockDepotCached;
ULONG prevFreeBlock;
/* All small blocks before this one are known to be in use. */
ULONG firstFreeSmallBlock;
/*
* Abstraction of the big block chains for the chains of the header.
*/