aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/compositebuffer.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-03-28 13:18:16 +0100
committerGitHub Enterprise <[email protected]>2024-03-28 13:18:16 +0100
commitdc0b3212127dbcd32b7e1efc4954164c616d3db5 (patch)
treea058efe8ea88667ff643d85aa9feeb9ac5974a47 /src/zencore/compositebuffer.cpp
parentGet raw size for compressed chunks correctly for `/prj/{project}/oplog/{log}/... (diff)
downloadzen-dc0b3212127dbcd32b7e1efc4954164c616d3db5.tar.xz
zen-dc0b3212127dbcd32b7e1efc4954164c616d3db5.zip
Faster reading of compressed buffer headers by not materializing entire source buffer (#28)
Diffstat (limited to 'src/zencore/compositebuffer.cpp')
-rw-r--r--src/zencore/compositebuffer.cpp74
1 files changed, 52 insertions, 22 deletions
diff --git a/src/zencore/compositebuffer.cpp b/src/zencore/compositebuffer.cpp
index d2b6d97f9..49870a304 100644
--- a/src/zencore/compositebuffer.cpp
+++ b/src/zencore/compositebuffer.cpp
@@ -133,24 +133,28 @@ CompositeBuffer::ViewOrCopyRange(uint64_t Offset,
std::function<UniqueBuffer(uint64_t Size)> Allocator) const
{
MemoryView View;
- IterateRange(Offset, Size, [Size, &View, &CopyBuffer, &Allocator, WriteView = MutableMemoryView()](MemoryView Segment) mutable {
- if (Size == Segment.GetSize())
- {
- View = Segment;
- }
- else
- {
- if (WriteView.IsEmpty())
+ IterateRange(
+ Offset,
+ Size,
+ [Size, &View, &CopyBuffer, &Allocator, WriteView = MutableMemoryView()](MemoryView Segment, const SharedBuffer& ViewOuter) mutable {
+ if (Segment.GetSize() == ViewOuter.GetSize())
+ {
+ // We assume that the segment of the buffer is kept in memory
+ View = Segment;
+ }
+ else
{
- if (CopyBuffer.GetSize() < Size)
+ if (WriteView.IsEmpty())
{
- CopyBuffer = Allocator(Size);
+ if (CopyBuffer.GetSize() < Size)
+ {
+ CopyBuffer = Allocator(Size);
+ }
+ View = WriteView = CopyBuffer.GetMutableView().Left(Size);
}
- View = WriteView = CopyBuffer.GetMutableView().Left(Size);
+ WriteView = WriteView.CopyFrom(Segment);
}
- WriteView = WriteView.CopyFrom(Segment);
- }
- });
+ });
return View;
}
@@ -263,18 +267,44 @@ CompositeBuffer::IterateRange(uint64_t Offset,
ZEN_ASSERT(Offset + Size <= GetSize());
for (const SharedBuffer& Segment : m_Segments)
{
- if (const uint64_t SegmentSize = Segment.GetSize(); Offset <= SegmentSize)
+ const uint64_t SegmentSize = Segment.GetSize();
+ if (Size == 0 && Offset == SegmentSize)
+ {
+ // Special case for getting the zero size end of a composite buffer
+ const MemoryView View = Segment.GetView().Mid(Offset, 0);
+ Visitor(View, Segment);
+ break;
+ }
+ if (Offset < SegmentSize)
{
- const MemoryView View = Segment.GetView().Mid(Offset, Size);
- Offset = 0;
- if (Size == 0 || !View.IsEmpty())
+ if (Offset == 0 && Size >= SegmentSize)
{
- Visitor(View, Segment);
+ const MemoryView View = Segment.GetView();
+ if (!View.IsEmpty())
+ {
+ Visitor(View, Segment);
+ }
+ Size -= View.GetSize();
+ if (Size == 0)
+ {
+ break;
+ }
}
- Size -= View.GetSize();
- if (Size == 0)
+ else
{
- break;
+ // If we only want a section of the segment, do a subrange so we don't have to materialize the entire iobuffer
+ IoBuffer SubRange(Segment.AsIoBuffer(), Offset, Min(Size, SegmentSize - Offset));
+ const MemoryView View = SubRange.GetView();
+ if (!View.IsEmpty())
+ {
+ Visitor(View, Segment);
+ }
+ Size -= View.GetSize();
+ if (Size == 0)
+ {
+ break;
+ }
+ Offset = 0;
}
}
else