implement MessageBuilder.unsafeConstructFromMessageReader()
This commit is contained in:
parent
a078df7e4d
commit
a55b869305
3 changed files with 41 additions and 1 deletions
|
@ -64,6 +64,30 @@ public final class BuilderArena implements Arena {
|
||||||
this.allocator = allocator;
|
this.allocator = allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a BuilderArena from a ReaderArena and uses the size of the largest segment
|
||||||
|
* as the next allocation size.
|
||||||
|
*/
|
||||||
|
BuilderArena(ReaderArena arena) {
|
||||||
|
this.segments = new ArrayList<SegmentBuilder>();
|
||||||
|
int largestSegment = SUGGESTED_FIRST_SEGMENT_WORDS*Constants.BYTES_PER_WORD;
|
||||||
|
for (int ii = 0; ii < arena.segments.size(); ++ii) {
|
||||||
|
SegmentReader segment = arena.segments.get(ii);
|
||||||
|
SegmentBuilder segmentBuilder = new SegmentBuilder(segment.buffer, this);
|
||||||
|
segmentBuilder.id = ii;
|
||||||
|
segmentBuilder.pos = segmentBuilder.capacity(); // buffer is pre-filled
|
||||||
|
segments.add(segmentBuilder);
|
||||||
|
|
||||||
|
// Find the largest segment for the allocation strategy.
|
||||||
|
largestSegment = Math.max(largestSegment, segment.buffer.capacity());
|
||||||
|
}
|
||||||
|
DefaultAllocator defaultAllocator = new DefaultAllocator(SUGGESTED_ALLOCATION_STRATEGY);
|
||||||
|
|
||||||
|
// Use largest segment as next size.
|
||||||
|
defaultAllocator.setNextAllocationSizeBytes(largestSegment);
|
||||||
|
this.allocator = defaultAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final SegmentReader tryGetSegment(int id) {
|
public final SegmentReader tryGetSegment(int id) {
|
||||||
return this.segments.get(id);
|
return this.segments.get(id);
|
||||||
|
|
|
@ -71,6 +71,22 @@ public final class MessageBuilder {
|
||||||
this.arena = new BuilderArena(new DefaultAllocator(), firstSegment);
|
this.arena = new BuilderArena(new DefaultAllocator(), firstSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MessageBuilder from a MessageReader. This constructor is private
|
||||||
|
* because it is unsafe. To use it, you must call `unsafeConstructFromMessageReader()`.
|
||||||
|
*/
|
||||||
|
private MessageBuilder(MessageReader messageReader) {
|
||||||
|
this.arena = new BuilderArena(messageReader.arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MessageBuilder from a MessageReader without copying the segments.
|
||||||
|
* This method should only be used on trusted data. Otherwise you may observe infinite
|
||||||
|
* loops or large memory allocations or index-out-of-bounds errors.
|
||||||
|
*/
|
||||||
|
public static MessageBuilder unsafeConstructFromMessageReader(MessageReader messageReader) {
|
||||||
|
return new MessageBuilder(messageReader);
|
||||||
|
}
|
||||||
|
|
||||||
private AnyPointer.Builder getRootInternal() {
|
private AnyPointer.Builder getRootInternal() {
|
||||||
if (this.arena.segments.isEmpty()) {
|
if (this.arena.segments.isEmpty()) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ public final class SegmentBuilder extends SegmentReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the total number of words the buffer can hold
|
// the total number of words the buffer can hold
|
||||||
private final int capacity() {
|
final int capacity() {
|
||||||
this.buffer.rewind();
|
this.buffer.rewind();
|
||||||
return this.buffer.remaining() / 8;
|
return this.buffer.remaining() / 8;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue