From d671d56f6292d0dafa46ca6e116fee7597c56b3f Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Sat, 20 Mar 2010 13:13:47 -0500 Subject: [PATCH] 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. --- dlls/ole32/storage32.c | 7 ++++++- dlls/ole32/storage32.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index f1706da..a15e3db 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -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; } diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index fad5d77..dfa5d1a 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -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. */ -- 1.6.3.3