implement scratch space reuse
This commit is contained in:
parent
3c60400dae
commit
755114c1a3
3 changed files with 46 additions and 0 deletions
|
@ -52,6 +52,18 @@ public final class BuilderArena implements Arena {
|
||||||
this.allocator = allocator;
|
this.allocator = allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BuilderArena(Allocator allocator, ByteBuffer firstSegment) {
|
||||||
|
this.segments = new ArrayList<SegmentBuilder>();
|
||||||
|
SegmentBuilder newSegment = new SegmentBuilder(
|
||||||
|
firstSegment,
|
||||||
|
this);
|
||||||
|
newSegment.buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
newSegment.id = 0;
|
||||||
|
this.segments.add(newSegment);
|
||||||
|
|
||||||
|
this.allocator = allocator;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final SegmentReader tryGetSegment(int id) {
|
public final SegmentReader tryGetSegment(int id) {
|
||||||
return this.segments.get(id);
|
return this.segments.get(id);
|
||||||
|
|
|
@ -40,10 +40,26 @@ public final class MessageBuilder {
|
||||||
allocationStrategy);
|
allocationStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new MessageBuilder from an Allocator.
|
||||||
|
*/
|
||||||
public MessageBuilder(Allocator allocator) {
|
public MessageBuilder(Allocator allocator) {
|
||||||
this.arena = new BuilderArena(allocator);
|
this.arena = new BuilderArena(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new MessageBuilder from an Allocator and a given first segment buffer.
|
||||||
|
* This is useful for reusing the first segment buffer between messages, to avoid
|
||||||
|
* repeated allocations.
|
||||||
|
*
|
||||||
|
* You MUST ensure that firstSegment contains only zeroes before calling this method.
|
||||||
|
* If you are reusing firstSegment from another message, then it suffices to call
|
||||||
|
* clearFirstSegment() on that message.
|
||||||
|
*/
|
||||||
|
public MessageBuilder(Allocator allocator, java.nio.ByteBuffer firstSegment) {
|
||||||
|
this.arena = new BuilderArena(allocator, firstSegment);
|
||||||
|
}
|
||||||
|
|
||||||
private AnyPointer.Builder getRootInternal() {
|
private AnyPointer.Builder getRootInternal() {
|
||||||
if (this.arena.segments.isEmpty()) {
|
if (this.arena.segments.isEmpty()) {
|
||||||
this.arena.allocate(1);
|
this.arena.allocate(1);
|
||||||
|
@ -78,4 +94,15 @@ public final class MessageBuilder {
|
||||||
public final java.nio.ByteBuffer[] getSegmentsForOutput() {
|
public final java.nio.ByteBuffer[] getSegmentsForOutput() {
|
||||||
return this.arena.getSegmentsForOutput();
|
return this.arena.getSegmentsForOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the first segment buffer to contain all zeros so that it can be reused in
|
||||||
|
* another message. (See the MessageBuilder(Allocator, ByteBuffer) constructor above.)
|
||||||
|
*
|
||||||
|
* After calling this method, the message will be corrupted. Therefore, you need to make
|
||||||
|
* sure to write the message (via getSegmentsForOutput()) before calling this.
|
||||||
|
*/
|
||||||
|
public final void clearFirstSegment() {
|
||||||
|
this.arena.segments.get(0).clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,4 +72,11 @@ public final class SegmentBuilder extends SegmentReader {
|
||||||
public final void put(int index, long value) {
|
public final void put(int index, long value) {
|
||||||
buffer.putLong(index * Constants.BYTES_PER_WORD, value);
|
buffer.putLong(index * Constants.BYTES_PER_WORD, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void clear() {
|
||||||
|
for (int ii = 0; ii < this.pos; ++ii) {
|
||||||
|
this.put(ii, 0);
|
||||||
|
}
|
||||||
|
this.pos = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue