Skip to content

Commit 08c0844

Browse files
Fix consolidation with transaction
1 parent d55b7e5 commit 08c0844

File tree

4 files changed

+86
-87
lines changed

4 files changed

+86
-87
lines changed

OpenMcdf.Tests/RootStorageTests.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,83 @@ public void Open(string fileName)
2828
Assert.ThrowsException<NotSupportedException>(() => rootStorage.StateBits = 0);
2929
}
3030

31+
[TestMethod]
32+
[DataRow(Version.V3)]
33+
[DataRow(Version.V4)]
34+
public void ConsolidateMemoryStream(Version version)
35+
{
36+
byte[] buffer = new byte[4096];
37+
38+
using MemoryStream memoryStream = new();
39+
using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen))
40+
{
41+
using (CfbStream stream = rootStorage.CreateStream("Test"))
42+
stream.Write(buffer, 0, buffer.Length);
43+
44+
Assert.AreEqual(1, rootStorage.EnumerateEntries().Count());
45+
46+
rootStorage.Flush(true);
47+
48+
int originalMemoryStreamLength = (int)memoryStream.Length;
49+
50+
rootStorage.Delete("Test");
51+
52+
rootStorage.Flush(true);
53+
54+
Assert.IsTrue(originalMemoryStreamLength > memoryStream.Length);
55+
}
56+
57+
using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen))
58+
{
59+
Assert.AreEqual(0, rootStorage.EnumerateEntries().Count());
60+
}
61+
}
62+
63+
[TestMethod]
64+
[DataRow(Version.V3, StorageModeFlags.None)]
65+
[DataRow(Version.V4, StorageModeFlags.Transacted)]
66+
public void ConsolidateFile(Version version, StorageModeFlags flags)
67+
{
68+
byte[] buffer = new byte[4096];
69+
70+
string fileName = Path.GetTempFileName();
71+
72+
try
73+
{
74+
using (var rootStorage = RootStorage.Create(fileName, version, flags))
75+
{
76+
using (CfbStream stream = rootStorage.CreateStream("Test"))
77+
stream.Write(buffer, 0, buffer.Length);
78+
79+
Assert.AreEqual(1, rootStorage.EnumerateEntries().Count());
80+
81+
if (flags.HasFlag(StorageModeFlags.Transacted))
82+
rootStorage.Commit();
83+
rootStorage.Flush(true);
84+
85+
long originalLength = new FileInfo(fileName).Length;
86+
87+
rootStorage.Delete("Test");
88+
89+
if (flags.HasFlag(StorageModeFlags.Transacted))
90+
rootStorage.Commit();
91+
rootStorage.Flush(true);
92+
93+
long consolidatedLength = new FileInfo(fileName).Length;
94+
Assert.IsTrue(originalLength > consolidatedLength);
95+
}
96+
97+
using (var rootStorage = RootStorage.OpenRead(fileName))
98+
{
99+
Assert.AreEqual(0, rootStorage.EnumerateEntries().Count());
100+
}
101+
}
102+
finally
103+
{
104+
File.Delete(fileName);
105+
}
106+
}
107+
31108
[TestMethod]
32109
[DataRow(Version.V3, 0)]
33110
[DataRow(Version.V3, 1)]

OpenMcdf.Tests/StorageTests.cs

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -274,79 +274,6 @@ public void DeleteStream(Version version)
274274
}
275275
}
276276

277-
[TestMethod]
278-
[DataRow(Version.V3)]
279-
[DataRow(Version.V4)]
280-
public void ConsolidateMemoryStream(Version version)
281-
{
282-
byte[] buffer = new byte[4096];
283-
284-
using MemoryStream memoryStream = new();
285-
using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen))
286-
{
287-
using (CfbStream stream = rootStorage.CreateStream("Test"))
288-
stream.Write(buffer, 0, buffer.Length);
289-
290-
Assert.AreEqual(1, rootStorage.EnumerateEntries().Count());
291-
292-
rootStorage.Flush(true);
293-
294-
int originalMemoryStreamLength = (int)memoryStream.Length;
295-
296-
rootStorage.Delete("Test");
297-
298-
rootStorage.Flush(true);
299-
300-
Assert.IsTrue(originalMemoryStreamLength > memoryStream.Length);
301-
}
302-
303-
using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen))
304-
{
305-
Assert.AreEqual(0, rootStorage.EnumerateEntries().Count());
306-
}
307-
}
308-
309-
[TestMethod]
310-
[DataRow(Version.V3)]
311-
[DataRow(Version.V4)]
312-
public void ConsolidateFile(Version version)
313-
{
314-
byte[] buffer = new byte[4096];
315-
316-
string fileName = Path.GetTempFileName();
317-
318-
try
319-
{
320-
using (var rootStorage = RootStorage.Create(fileName, version))
321-
{
322-
using (CfbStream stream = rootStorage.CreateStream("Test"))
323-
stream.Write(buffer, 0, buffer.Length);
324-
325-
Assert.AreEqual(1, rootStorage.EnumerateEntries().Count());
326-
327-
rootStorage.Flush(true);
328-
329-
long originalLength = new FileInfo(fileName).Length;
330-
331-
rootStorage.Delete("Test");
332-
333-
rootStorage.Flush(true);
334-
335-
long consolidatedLength = new FileInfo(fileName).Length;
336-
Assert.IsTrue(originalLength > consolidatedLength);
337-
}
338-
339-
using (var rootStorage = RootStorage.OpenRead(fileName))
340-
{
341-
Assert.AreEqual(0, rootStorage.EnumerateEntries().Count());
342-
}
343-
}
344-
finally
345-
{
346-
File.Delete(fileName);
347-
}
348-
}
349-
350277
[TestMethod]
351278
[DataRow(Version.V3)]
352279
[DataRow(Version.V4)]

OpenMcdf/RootContext.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenMcdf;
44

5+
[Flags]
56
enum IOContextFlags
67
{
78
None = 0,
@@ -188,12 +189,6 @@ public void ExtendStreamLength(long length)
188189
isDirty = true;
189190
}
190191

191-
public void Consolidate(long length)
192-
{
193-
BaseStream.SetLength(length);
194-
Length = length;
195-
}
196-
197192
public void WriteHeader()
198193
{
199194
CfbBinaryWriter writer = Writer;

OpenMcdf/RootStorage.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,25 +154,25 @@ void Consolidate()
154154
{
155155
// TODO: Consolidate by defragmentation instead of copy
156156

157+
Stream baseStream = Context.BaseStream;
157158
Stream? destinationStream = null;
158159

159160
try
160161
{
161-
if (Context.BaseStream is MemoryStream)
162-
destinationStream = new MemoryStream((int)Context.BaseStream.Length);
163-
else if (Context.BaseStream is FileStream)
162+
if (baseStream is MemoryStream)
163+
destinationStream = new MemoryStream((int)baseStream.Length);
164+
else if (baseStream is FileStream)
164165
destinationStream = File.Create(Path.GetTempFileName());
165166
else
166167
throw new NotSupportedException("Unsupported stream type for consolidation.");
167168

168-
using (RootStorage destinationStorage = Create(destinationStream, Context.Version, storageModeFlags | StorageModeFlags.LeaveOpen))
169+
using (RootStorage destinationStorage = Create(destinationStream, Context.Version, StorageModeFlags.LeaveOpen))
169170
CopyTo(destinationStorage);
170171

171-
Context.BaseStream.Position = 0;
172-
destinationStream.Position = 0;
172+
destinationStream.CopyAllTo(baseStream);
173173

174-
destinationStream.CopyTo(Context.BaseStream);
175-
Context.Consolidate(destinationStream.Length);
174+
IOContextFlags contextFlags = ToIOContextFlags(storageModeFlags);
175+
_ = new RootContext(ContextSite, baseStream, Version.Unknown, contextFlags);
176176
}
177177
catch
178178
{

0 commit comments

Comments
 (0)