Vincent Povirk : ole32: Always move unmodified streams instead of copying on commit.

Alexandre Julliard julliard at winehq.org
Thu May 6 11:13:24 CDT 2010


Module: wine
Branch: master
Commit: e40afcb2b66bcd8609cb086f00b7e5ce3f11dcb2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e40afcb2b66bcd8609cb086f00b7e5ce3f11dcb2

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Tue May  4 17:40:55 2010 -0500

ole32: Always move unmodified streams instead of copying on commit.

---

 dlls/ole32/storage32.c |  107 ++++++++++++++++++++++++++++++++++++++++++-----
 dlls/ole32/storage32.h |   11 +++++
 2 files changed, 106 insertions(+), 12 deletions(-)

diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index a9354c9..8bae897 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -2351,6 +2351,21 @@ static BlockChainStream **StorageImpl_GetCachedBlockChainStream(StorageImpl *Thi
   return &This->blockChainCache[free_index];
 }
 
+static void StorageImpl_DeleteCachedBlockChainStream(StorageImpl *This, DirRef index)
+{
+  int i;
+
+  for (i=0; i<BLOCKCHAIN_CACHE_SIZE; i++)
+  {
+    if (This->blockChainCache[i] && This->blockChainCache[i]->ownerDirEntry == index)
+    {
+      BlockChainStream_Destroy(This->blockChainCache[i]);
+      This->blockChainCache[i] = NULL;
+      return;
+    }
+  }
+}
+
 static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index,
   ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
 {
@@ -2542,6 +2557,30 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
   }
 }
 
+static HRESULT StorageImpl_StreamLink(StorageBaseImpl *base, DirRef dst,
+  DirRef src)
+{
+  StorageImpl *This = (StorageImpl*)base;
+  DirEntry dst_data, src_data;
+  HRESULT hr;
+
+  hr = StorageImpl_ReadDirEntry(This, dst, &dst_data);
+
+  if (SUCCEEDED(hr))
+    hr = StorageImpl_ReadDirEntry(This, src, &src_data);
+
+  if (SUCCEEDED(hr))
+  {
+    StorageImpl_DeleteCachedBlockChainStream(This, src);
+    dst_data.startingBlock = src_data.startingBlock;
+    dst_data.size = src_data.size;
+
+    hr = StorageImpl_WriteDirEntry(This, dst, &dst_data);
+  }
+
+  return hr;
+}
+
 /*
  * Virtual function table for the IStorage32Impl class.
  */
@@ -2577,7 +2616,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl =
   StorageImpl_DestroyDirEntry,
   StorageImpl_StreamReadAt,
   StorageImpl_StreamWriteAt,
-  StorageImpl_StreamSetSize
+  StorageImpl_StreamSetSize,
+  StorageImpl_StreamLink
 };
 
 static HRESULT StorageImpl_Construct(
@@ -4298,8 +4338,9 @@ static void TransactedSnapshotImpl_DestroyTemporaryCopy(
     {
       entry = &This->entries[cursor];
 
-      StorageBaseImpl_StreamSetSize(This->transactedParent,
-        entry->newTransactedParentEntry, zero);
+      if (entry->stream_dirty)
+        StorageBaseImpl_StreamSetSize(This->transactedParent,
+          entry->newTransactedParentEntry, zero);
 
       StorageBaseImpl_DestroyDirEntry(This->transactedParent,
         entry->newTransactedParentEntry);
@@ -4366,9 +4407,19 @@ static HRESULT TransactedSnapshotImpl_CopyTree(TransactedSnapshotImpl* This)
         return hr;
       }
 
-      hr = StorageBaseImpl_CopyStream(
-        This->transactedParent, entry->newTransactedParentEntry,
-        (StorageBaseImpl*)This, cursor);
+      if (entry->stream_dirty)
+      {
+        hr = StorageBaseImpl_CopyStream(
+          This->transactedParent, entry->newTransactedParentEntry,
+          This->scratch, entry->stream_entry);
+      }
+      else if (entry->data.size.QuadPart)
+      {
+        hr = StorageBaseImpl_StreamLink(
+          This->transactedParent, entry->newTransactedParentEntry,
+          entry->transactedParentEntry);
+      }
+
       if (FAILED(hr))
       {
         cursor = TransactedSnapshotImpl_FindNextChild(This, cursor);
@@ -4457,12 +4508,8 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit(
         else if (entry->read && entry->transactedParentEntry != entry->newTransactedParentEntry)
         {
           if (entry->transactedParentEntry != DIRENTRY_NULL)
-          {
-            StorageBaseImpl_StreamSetSize(This->transactedParent,
-              entry->transactedParentEntry, zero);
             StorageBaseImpl_DestroyDirEntry(This->transactedParent,
               entry->transactedParentEntry);
-          }
           if (entry->stream_dirty)
           {
             StorageBaseImpl_StreamSetSize(This->scratch, entry->stream_entry, zero);
@@ -4739,6 +4786,31 @@ static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base,
   return hr;
 }
 
+static HRESULT TransactedSnapshotImpl_StreamLink(StorageBaseImpl *base,
+  DirRef dst, DirRef src)
+{
+  TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base;
+  HRESULT hr;
+  TransactedDirEntry *dst_entry, *src_entry;
+
+  hr = TransactedSnapshotImpl_EnsureReadEntry(This, src);
+  if (FAILED(hr)) return hr;
+
+  hr = TransactedSnapshotImpl_EnsureReadEntry(This, dst);
+  if (FAILED(hr)) return hr;
+
+  dst_entry = &This->entries[dst];
+  src_entry = &This->entries[src];
+
+  dst_entry->stream_dirty = src_entry->stream_dirty;
+  dst_entry->stream_entry = src_entry->stream_entry;
+  dst_entry->transactedParentEntry = src_entry->transactedParentEntry;
+  dst_entry->newTransactedParentEntry = src_entry->newTransactedParentEntry;
+  dst_entry->data.size = src_entry->data.size;
+
+  return S_OK;
+}
+
 static const IStorageVtbl TransactedSnapshotImpl_Vtbl =
 {
     StorageBaseImpl_QueryInterface,
@@ -4771,7 +4843,8 @@ static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl =
   TransactedSnapshotImpl_DestroyDirEntry,
   TransactedSnapshotImpl_StreamReadAt,
   TransactedSnapshotImpl_StreamWriteAt,
-  TransactedSnapshotImpl_StreamSetSize
+  TransactedSnapshotImpl_StreamSetSize,
+  TransactedSnapshotImpl_StreamLink
 };
 
 static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage,
@@ -4974,6 +5047,15 @@ static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base,
     index, newsize);
 }
 
+static HRESULT StorageInternalImpl_StreamLink(StorageBaseImpl *base,
+  DirRef dst, DirRef src)
+{
+  StorageInternalImpl* This = (StorageInternalImpl*) base;
+
+  return StorageBaseImpl_StreamLink(This->parentStorage,
+    dst, src);
+}
+
 /******************************************************************************
 **
 ** Storage32InternalImpl_Commit
@@ -5333,7 +5415,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl =
   StorageInternalImpl_DestroyDirEntry,
   StorageInternalImpl_StreamReadAt,
   StorageInternalImpl_StreamWriteAt,
-  StorageInternalImpl_StreamSetSize
+  StorageInternalImpl_StreamSetSize,
+  StorageInternalImpl_StreamLink
 };
 
 /******************************************************************************
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index f25351b..19f3f2d 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -263,6 +263,7 @@ struct StorageBaseImplVtbl {
   HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
   HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
   HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
+  HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef);
 };
 
 static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
@@ -320,6 +321,16 @@ static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
   return This->baseVtbl->StreamSetSize(This, index, newsize);
 }
 
+/* Make dst point to the same stream that src points to. Other stream operations
+ * will not work properly for entries that point to the same stream, so this
+ * must be a very temporary state, and only one entry pointing to a given stream
+ * may be reachable at any given time. */
+static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This,
+  DirRef dst, DirRef src)
+{
+  return This->baseVtbl->StreamLink(This, dst, src);
+}
+
 /****************************************************************************
  * StorageBaseImpl stream list handlers
  */




More information about the wine-cvs mailing list