Vincent Povirk : ole32: Cache all extended big block depot locations.
Alexandre Julliard
julliard at winehq.org
Thu Nov 4 12:52:50 CDT 2010
Module: wine
Branch: master
Commit: 8d101b269db5423d2f26ddf42869651f8a468661
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d101b269db5423d2f26ddf42869651f8a468661
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Apr 19 16:07:09 2010 -0500
ole32: Cache all extended big block depot locations.
---
dlls/ole32/storage32.c | 78 ++++++++++++++++++++++++++++++++++++-----------
dlls/ole32/storage32.h | 2 +
2 files changed, 61 insertions(+), 19 deletions(-)
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 5c58201..311f2ae 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -2768,6 +2768,40 @@ static HRESULT StorageImpl_Construct(
This->firstFreeSmallBlock = 0;
+ /* Read the extended big block depot locations. */
+ if (This->extBigBlockDepotCount != 0)
+ {
+ ULONG current_block = This->extBigBlockDepotStart;
+ ULONG cache_size = This->extBigBlockDepotCount * 2;
+ int i;
+
+ This->extBigBlockDepotLocations = HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * cache_size);
+ if (!This->extBigBlockDepotLocations)
+ {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
+
+ This->extBigBlockDepotLocationsSize = cache_size;
+
+ for (i=0; i<This->extBigBlockDepotCount; i++)
+ {
+ if (current_block == BLOCK_END_OF_CHAIN)
+ {
+ WARN("File has too few extended big block depot blocks.\n");
+ hr = STG_E_DOCFILECORRUPT;
+ goto end;
+ }
+ This->extBigBlockDepotLocations[i] = current_block;
+ current_block = Storage32Impl_GetNextExtendedBlock(This, current_block);
+ }
+ }
+ else
+ {
+ This->extBigBlockDepotLocations = NULL;
+ This->extBigBlockDepotLocationsSize = 0;
+ }
+
/*
* Create the block chain abstractions.
*/
@@ -2884,6 +2918,8 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
StorageImpl_Invalidate(iface);
+ HeapFree(GetProcessHeap(), 0, This->extBigBlockDepotLocations);
+
BlockChainStream_Destroy(This->smallBlockRootChain);
BlockChainStream_Destroy(This->rootBlockChain);
BlockChainStream_Destroy(This->smallBlockDepotChain);
@@ -3097,18 +3133,14 @@ static ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This, ULONG depotIndex)
ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock;
ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock;
ULONG blockIndex = BLOCK_UNUSED;
- ULONG extBlockIndex = This->extBigBlockDepotStart;
+ ULONG extBlockIndex;
assert(depotIndex >= COUNT_BBDEPOTINHEADER);
- if (This->extBigBlockDepotStart == BLOCK_END_OF_CHAIN)
+ if (extBlockCount >= This->extBigBlockDepotCount)
return BLOCK_UNUSED;
- while (extBlockCount > 0)
- {
- extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex);
- extBlockCount--;
- }
+ extBlockIndex = This->extBigBlockDepotLocations[extBlockCount];
if (extBlockIndex != BLOCK_UNUSED)
StorageImpl_ReadDWordFromBigBlock(This, extBlockIndex,
@@ -3130,15 +3162,13 @@ static void Storage32Impl_SetExtDepotBlock(StorageImpl* This, ULONG depotIndex,
ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER;
ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock;
ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock;
- ULONG extBlockIndex = This->extBigBlockDepotStart;
+ ULONG extBlockIndex;
assert(depotIndex >= COUNT_BBDEPOTINHEADER);
- while (extBlockCount > 0)
- {
- extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex);
- extBlockCount--;
- }
+ assert(extBlockCount < This->extBigBlockDepotCount);
+
+ extBlockIndex = This->extBigBlockDepotLocations[extBlockCount];
if (extBlockIndex != BLOCK_UNUSED)
{
@@ -3175,14 +3205,10 @@ static ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This)
}
else
{
- unsigned int i;
/*
- * Follow the chain to the last one.
+ * Find the last existing extended block.
*/
- for (i = 0; i < (numExtBlocks - 1); i++)
- {
- nextExtBlock = Storage32Impl_GetNextExtendedBlock(This, nextExtBlock);
- }
+ nextExtBlock = This->extBigBlockDepotLocations[This->extBigBlockDepotCount-1];
/*
* Add the new extended block to the chain.
@@ -3197,6 +3223,20 @@ static ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This)
memset(depotBuffer, BLOCK_UNUSED, This->bigBlockSize);
StorageImpl_WriteBigBlock(This, index, depotBuffer);
+ /* Add the block to our cache. */
+ if (This->extBigBlockDepotLocationsSize == numExtBlocks)
+ {
+ ULONG new_cache_size = (This->extBigBlockDepotLocationsSize+1)*2;
+ ULONG *new_cache = HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * new_cache_size);
+
+ memcpy(new_cache, This->extBigBlockDepotLocations, sizeof(ULONG) * This->extBigBlockDepotLocationsSize);
+ HeapFree(GetProcessHeap(), 0, This->extBigBlockDepotLocations);
+
+ This->extBigBlockDepotLocations = new_cache;
+ This->extBigBlockDepotLocationsSize = new_cache_size;
+ }
+ This->extBigBlockDepotLocations[numExtBlocks] = index;
+
return index;
}
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 36d0e2f..72a5fe7 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -353,6 +353,8 @@ struct StorageImpl
ULONG smallBlockLimit;
ULONG smallBlockDepotStart;
ULONG extBigBlockDepotStart;
+ ULONG *extBigBlockDepotLocations;
+ ULONG extBigBlockDepotLocationsSize;
ULONG extBigBlockDepotCount;
ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
More information about the wine-cvs
mailing list