replace PipelineOp[] with short[]

This commit is contained in:
Vaci Koblizek 2020-11-27 11:12:40 +00:00
parent a53f7db25e
commit 789d2df6e4
5 changed files with 43 additions and 68 deletions

View file

@ -398,7 +398,7 @@ final class RpcState<VatId> {
LOGGER.fine(() -> this.toString() + ": > BOOTSTRAP question=" + question.id); LOGGER.fine(() -> this.toString() + ": > BOOTSTRAP question=" + question.id);
message.send(); message.send();
return pipeline.getPipelinedCap(new PipelineOp[0]); return pipeline.getPipelinedCap(new short[0]);
} }
/** /**
@ -1534,7 +1534,7 @@ final class RpcState<VatId> {
private RpcResponse resolved; private RpcResponse resolved;
private Throwable broken; private Throwable broken;
private final HashMap<List<PipelineOp>, ClientHook> clientMap = new HashMap<>(); private final HashMap<List<Short>, ClientHook> clientMap = new HashMap<>();
private final CompletableFuture<RpcResponse> redirectLater; private final CompletableFuture<RpcResponse> redirectLater;
private final CompletableFuture<RpcResponse> resolveSelf; private final CompletableFuture<RpcResponse> resolveSelf;
@ -1566,9 +1566,11 @@ final class RpcState<VatId> {
} }
@Override @Override
public ClientHook getPipelinedCap(PipelineOp[] ops) { public ClientHook getPipelinedCap(short[] ops) {
// TODO avoid conversion to/from ArrayList? var key = new ArrayList<Short>(ops.length);
var key = new ArrayList<>(Arrays.asList(ops)); for (short op: ops) {
key.add(op);
}
return this.clientMap.computeIfAbsent(key, k -> { return this.clientMap.computeIfAbsent(key, k -> {
return switch (state) { return switch (state) {
@ -2003,11 +2005,11 @@ final class RpcState<VatId> {
private class PipelineClient extends RpcClient { private class PipelineClient extends RpcClient {
private final QuestionRef questionRef; private final QuestionRef questionRef;
private final PipelineOp[] ops; private final short[] ops;
PipelineClient(QuestionRef questionRef, PipelineOp[] ops) { PipelineClient(QuestionRef questionRef, short[] ops) {
this.questionRef = questionRef; this.questionRef = questionRef;
this.ops = ops; this.ops = ops.clone();
} }
@Override @Override
@ -2037,34 +2039,35 @@ final class RpcState<VatId> {
} }
} }
static void FromPipelineOps(PipelineOp[] ops, RpcProtocol.PromisedAnswer.Builder builder) { static void FromPipelineOps(short[] ops, RpcProtocol.PromisedAnswer.Builder builder) {
var transforms = builder.initTransform(ops.length); var transforms = builder.initTransform(ops.length);
for (int ii = 0; ii < ops.length; ++ii) { for (int ii = 0; ii < ops.length; ++ii) {
var transform = transforms.get(ii); var transform = transforms.get(ii);
switch (ops[ii].type) { var pointerIndex = ops[ii];
case NOOP -> transform.setNoop(null); if (pointerIndex < 0) {
case GET_POINTER_FIELD -> transform.setGetPointerField(ops[ii].pointerIndex); transform.setNoop(null);
}
else {
transform.setGetPointerField(pointerIndex);
} }
} }
} }
static PipelineOp[] ToPipelineOps(RpcProtocol.PromisedAnswer.Reader reader) { static short[] ToPipelineOps(RpcProtocol.PromisedAnswer.Reader reader) {
var transforms = reader.getTransform(); var transforms = reader.getTransform();
var ops = new PipelineOp[transforms.size()]; var ops = new short[transforms.size()];
for (int ii = 0; ii < ops.length; ++ii) { for (int ii = 0; ii < ops.length; ++ii) {
var transform = transforms.get(ii); var transform = transforms.get(ii);
switch (transform.which()) { switch (transform.which()) {
case NOOP: case NOOP:
ops[ii] = PipelineOp.Noop(); // TODO null? ops[ii] = -1;
break; break;
case GET_POINTER_FIELD: case GET_POINTER_FIELD:
ops[ii] = PipelineOp.PointerField(transform.getGetPointerField()); ops[ii] = transform.getGetPointerField();
break; break;
default: case _NOT_IN_SCHEMA:
// TODO improve error handling here
// Unsupported pipeline ops
return null; return null;
} };
} }
return ops; return ops;
} }

View file

@ -80,18 +80,13 @@ public final class AnyPointer {
return factory.fromPointerReader(this.segment, this.capTable, this.pointer, this.nestingLimit); return factory.fromPointerReader(this.segment, this.capTable, this.pointer, this.nestingLimit);
} }
public final ClientHook getPipelinedCap(PipelineOp[] ops) { public final ClientHook getPipelinedCap(short[] ops) {
AnyPointer.Reader any = this; AnyPointer.Reader any = this;
for (var op: ops) { for (var pointerIndex: ops) {
switch (op.type) { if (pointerIndex >= 0) {
case NOOP: var reader = WireHelpers.readStructPointer(any.segment, any.capTable, any.pointer, null, 0, any.nestingLimit);
break; any = reader._getPointerField(AnyPointer.factory, pointerIndex);
case GET_POINTER_FIELD:
var index = op.pointerIndex;
var reader = WireHelpers.readStructPointer(any.segment, any.capTable, any.pointer, null, 0, any.nestingLimit);
any = reader._getPointerField(AnyPointer.factory, op.pointerIndex);
break;
} }
} }
return WireHelpers.readCapabilityPointer(any.segment, any.capTable, any.pointer, 0); return WireHelpers.readCapabilityPointer(any.segment, any.capTable, any.pointer, 0);
@ -151,13 +146,13 @@ public final class AnyPointer {
implements org.capnproto.Pipeline { implements org.capnproto.Pipeline {
final PipelineHook hook; final PipelineHook hook;
private final PipelineOp[] ops; private final short[] ops;
public Pipeline(PipelineHook hook) { public Pipeline(PipelineHook hook) {
this(hook, new PipelineOp[0]); this(hook, new short[0]);
} }
Pipeline(PipelineHook hook, PipelineOp[] ops) { Pipeline(PipelineHook hook, short[] ops) {
this.hook = hook; this.hook = hook;
this.ops = ops; this.ops = ops;
} }
@ -181,9 +176,9 @@ public final class AnyPointer {
} }
public Pipeline getPointerField(short pointerIndex) { public Pipeline getPointerField(short pointerIndex) {
var newOps = new PipelineOp[this.ops.length + 1]; var newOps = new short[this.ops.length + 1];
System.arraycopy(this.ops, 0, newOps, 0, this.ops.length); System.arraycopy(this.ops, 0, newOps, 0, this.ops.length);
newOps[this.ops.length] = PipelineOp.PointerField(pointerIndex); newOps[this.ops.length] = pointerIndex;
return new Pipeline(this.hook, newOps); return new Pipeline(this.hook, newOps);
} }
} }

View file

@ -465,7 +465,7 @@ public final class Capability {
} }
@Override @Override
public final ClientHook getPipelinedCap(PipelineOp[] ops) { public final ClientHook getPipelinedCap(short[] ops) {
return this.results.getPipelinedCap(ops); return this.results.getPipelinedCap(ops);
} }
} }
@ -689,7 +689,7 @@ public final class Capability {
private final CompletableFuture<PipelineHook> promise; private final CompletableFuture<PipelineHook> promise;
PipelineHook redirect; PipelineHook redirect;
private final Map<List<PipelineOp>, ClientHook> clientMap = new HashMap<>(); private final Map<List<Short>, ClientHook> clientMap = new HashMap<>();
QueuedPipeline(CompletableFuture<PipelineHook> promise) { QueuedPipeline(CompletableFuture<PipelineHook> promise) {
this.promise = promise.whenComplete((pipeline, exc) -> { this.promise = promise.whenComplete((pipeline, exc) -> {
@ -700,11 +700,16 @@ public final class Capability {
} }
@Override @Override
public final ClientHook getPipelinedCap(PipelineOp[] ops) { public final ClientHook getPipelinedCap(short[] ops) {
if (redirect != null) { if (redirect != null) {
return redirect.getPipelinedCap(ops); return redirect.getPipelinedCap(ops);
} }
var key = Arrays.asList(ops);
var key = new ArrayList<Short>(ops.length);
for (short op: ops) {
key.add(op);
}
return this.clientMap.computeIfAbsent(key, return this.clientMap.computeIfAbsent(key,
k -> new QueuedClient(this.promise.thenApply( k -> new QueuedClient(this.promise.thenApply(
pipeline -> pipeline.getPipelinedCap(ops)))); pipeline -> pipeline.getPipelinedCap(ops))));

View file

@ -2,7 +2,7 @@ package org.capnproto;
public interface PipelineHook { public interface PipelineHook {
ClientHook getPipelinedCap(PipelineOp[] ops); ClientHook getPipelinedCap(short[] ops);
default void cancel(Throwable exc) { default void cancel(Throwable exc) {
} }

View file

@ -1,28 +0,0 @@
package org.capnproto;
final class PipelineOp {
// TODO just use array of Short?
enum Type {
NOOP,
GET_POINTER_FIELD
}
final PipelineOp.Type type;
final short pointerIndex;
private PipelineOp(PipelineOp.Type type, short pointerIndex) {
this.type = type;
this.pointerIndex = pointerIndex;
}
static PipelineOp Noop() {
return new PipelineOp(Type.NOOP, (short) 0);
}
static PipelineOp PointerField(short pointerIndex) {
return new PipelineOp(Type.GET_POINTER_FIELD, pointerIndex);
}
}