Skip to content

Commit 53b94f1

Browse files
authored
rpc: linear time batch response matching (#23856)
This avoids quadratic time complexity in the lookup of the batch element corresponding to an RPC response. Unfortunately, the new approach requires additional memory for the mapping from ID to index. Fixes #22805
1 parent 03bc8b7 commit 53b94f1

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

rpc/client.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package rpc
1818

1919
import (
20-
"bytes"
2120
"context"
2221
"encoding/json"
2322
"errors"
@@ -360,7 +359,10 @@ func (c *Client) BatchCall(b []BatchElem) error {
360359
//
361360
// Note that batch calls may not be executed atomically on the server side.
362361
func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
363-
msgs := make([]*jsonrpcMessage, len(b))
362+
var (
363+
msgs = make([]*jsonrpcMessage, len(b))
364+
byID = make(map[string]int, len(b))
365+
)
364366
op := &requestOp{
365367
ids: make([]json.RawMessage, len(b)),
366368
resp: make(chan *jsonrpcMessage, len(b)),
@@ -372,6 +374,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
372374
}
373375
msgs[i] = msg
374376
op.ids[i] = msg.ID
377+
byID[string(msg.ID)] = i
375378
}
376379

377380
var err error
@@ -391,13 +394,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error {
391394
// Find the element corresponding to this response.
392395
// The element is guaranteed to be present because dispatch
393396
// only sends valid IDs to our channel.
394-
var elem *BatchElem
395-
for i := range msgs {
396-
if bytes.Equal(msgs[i].ID, resp.ID) {
397-
elem = &b[i]
398-
break
399-
}
400-
}
397+
elem := &b[byID[string(resp.ID)]]
401398
if resp.Error != nil {
402399
elem.Error = resp.Error
403400
continue

0 commit comments

Comments
 (0)