Fix the cancelled multipart merge cleanup path.

This commit is contained in:
Ahmed Yasin Koculu
2026-06-08 02:01:56 +02:00
parent cb9660bf91
commit f2e09cf869
2 changed files with 72 additions and 13 deletions
@@ -270,7 +270,51 @@ public sealed class BottomSegmentMergeTests
}
}
static ZoneTreeOptions<int, int> CreateMultiPartBottomMergeOptions()
[Test]
public void MultiPartCreatorDropBeforeHeaderIsWrittenDropsPendingPart()
{
var options = CreateMultiPartBottomMergeOptions(
"data/MultiPartCreatorDropBeforeHeaderIsWrittenDropsPendingPart");
var idProvider = new IncrementalIdProvider();
try
{
using var creator = new MultiPartDiskSegmentCreator<int, int>(
options,
idProvider);
creator.Append(1, 1, IteratorPosition.None);
Assert.That(
options.RandomAccessDeviceManager.DeviceExists(
2,
DiskSegmentConstants.DataCategory,
isCompressed: true),
Is.True);
Assert.DoesNotThrow(() => creator.DropDiskSegment());
Assert.That(
options.RandomAccessDeviceManager.DeviceExists(
1,
DiskSegmentConstants.MultiPartDiskSegmentCategory,
isCompressed: false),
Is.False);
Assert.That(
options.RandomAccessDeviceManager.DeviceExists(
2,
DiskSegmentConstants.DataCategory,
isCompressed: true),
Is.False);
Assert.That(options.RandomAccessDeviceManager.DeviceCount, Is.EqualTo(0));
}
finally
{
options.RandomAccessDeviceManager.DropStore();
}
}
static ZoneTreeOptions<int, int> CreateMultiPartBottomMergeOptions(
string dataDirectory = "data/PartialMultiPartBottomMerge")
{
var logger = new ConsoleLogger(LogLevel.Error);
var options = new ZoneTreeOptions<int, int>
@@ -283,7 +327,7 @@ public sealed class BottomSegmentMergeTests
RandomAccessDeviceManager = new RandomAccessDeviceManager(
logger,
new InMemoryFileStreamProvider(),
"data/PartialMultiPartBottomMerge"),
dataDirectory),
DiskSegmentOptions = new DiskSegmentOptions
{
DiskSegmentMode = DiskSegmentMode.MultiPartDiskSegment,
@@ -133,6 +133,7 @@ public sealed class MultiPartDiskSegmentCreator<TKey, TValue> : IDiskSegmentCrea
if (NextCreator.Length == 0)
{
NextCreator.DropDiskSegment();
NextCreator = null;
}
else
{
@@ -140,6 +141,7 @@ public sealed class MultiPartDiskSegmentCreator<TKey, TValue> : IDiskSegmentCrea
PartValues.Add(LastAppendedValue);
var part = NextCreator.CreateReadOnlyDiskSegment();
Parts.Add(part);
NextCreator = null;
}
WriteMultiDiskSegment();
@@ -238,21 +240,34 @@ public sealed class MultiPartDiskSegmentCreator<TKey, TValue> : IDiskSegmentCrea
continue;
part.Drop();
}
using var multiDevice = Options.RandomAccessDeviceManager
.GetReadOnlyDevice(
SegmentId,
DiskSegmentConstants.MultiPartDiskSegmentCategory,
isCompressed: false,
compressionBlockSize: 0,
MultiPartDiskSegment<TKey, TValue>.MultiPartHeaderCompressionMethod,
MultiPartDiskSegment<TKey, TValue>.MultiPartHeaderCompressionLevel);
NextCreator?.DropDiskSegment();
NextCreator = null;
var randomAccessDeviceManager = Options.RandomAccessDeviceManager;
if (!randomAccessDeviceManager.DeviceExists(
SegmentId,
DiskSegmentConstants.MultiPartDiskSegmentCategory,
isCompressed: false))
{
return;
}
using var multiDevice = randomAccessDeviceManager.GetReadOnlyDevice(
SegmentId,
DiskSegmentConstants.MultiPartDiskSegmentCategory,
isCompressed: false,
compressionBlockSize: 0,
MultiPartDiskSegment<TKey, TValue>.MultiPartHeaderCompressionMethod,
MultiPartDiskSegment<TKey, TValue>.MultiPartHeaderCompressionLevel);
multiDevice.Delete();
Options.RandomAccessDeviceManager
.RemoveReadOnlyDevice(SegmentId, DiskSegmentConstants.MultiPartDiskSegmentCategory);
randomAccessDeviceManager.RemoveReadOnlyDevice(
SegmentId,
DiskSegmentConstants.MultiPartDiskSegmentCategory);
}
public void Dispose()
{
}
}
}