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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
public final SegmentReader tryGetSegment(int id) {
|
||||
return this.segments.get(id);
|
||||
|
|
|
@ -71,6 +71,22 @@ public final class MessageBuilder {
|
|||
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() {
|
||||
if (this.arena.segments.isEmpty()) {
|
||||
|
|
|
@ -35,7 +35,7 @@ public final class SegmentBuilder extends SegmentReader {
|
|||
}
|
||||
|
||||
// the total number of words the buffer can hold
|
||||
private final int capacity() {
|
||||
final int capacity() {
|
||||
this.buffer.rewind();
|
||||
return this.buffer.remaining() / 8;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue