Skip to content

Commit

Permalink
Improve events heap allocations (#27)
Browse files Browse the repository at this point in the history
* Significantly lower number of heap allocations that should be required by events

* Use EmitEvent instead of EmitEvents
  • Loading branch information
ValarDragon authored and sunnya97 committed Nov 17, 2021
1 parent 9c13779 commit a32faa9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 25 deletions.
33 changes: 20 additions & 13 deletions types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,28 @@ func NewEventManager() *EventManager {
return &EventManager{EmptyEvents()}
}

// Increase Capacity increases the capacity of the EventManager,
// which is quite useful when many events are planned to be created.
func (em *EventManager) IncreaseCapacity(capacity int) {
events := em.events.getUnderlyingSlice()
if cap(events) < capacity {
em.events = make(Events, 0, capacity)
em.events = append(em.events, events...)
}
}

func (em *EventManager) Events() Events { return em.events }

// EmitEvent stores a single Event object.
// Deprecated: Use EmitTypedEvent
func (em *EventManager) EmitEvent(event Event) {
em.events = em.events.AppendEvent(event)
em.events = append(em.events, event)
}

// EmitEvents stores a series of Event objects.
// Deprecated: Use EmitTypedEvents
func (em *EventManager) EmitEvents(events Events) {
em.events = em.events.AppendEvents(events)
em.events = append(em.events, events...)
}

// ABCIEvents returns all stored Event objects as abci.Event objects.
Expand Down Expand Up @@ -153,7 +163,10 @@ type (
// NewEvent creates a new Event object with a given type and slice of one or more
// attributes.
func NewEvent(ty string, attrs ...Attribute) Event {
e := Event{Type: ty}
e := Event{
Type: ty,
Attributes: make([]abci.EventAttribute, 0, len(attrs)),
}

for _, attr := range attrs {
e.Attributes = append(e.Attributes, attr.ToKVPair())
Expand All @@ -178,7 +191,7 @@ func (a Attribute) String() string {

// ToKVPair converts an Attribute object into a Tendermint key/value pair.
func (a Attribute) ToKVPair() abci.EventAttribute {
return abci.EventAttribute{Key: toBytes(a.Key), Value: toBytes(a.Value)}
return abci.EventAttribute{Key: []byte(a.Key), Value: []byte(a.Value)}
}

// AppendAttributes adds one or more attributes to an Event.
Expand Down Expand Up @@ -210,15 +223,9 @@ func (e Events) ToABCIEvents() []abci.Event {
return res
}

func toBytes(i interface{}) []byte {
switch x := i.(type) {
case []uint8:
return x
case string:
return []byte(x)
default:
panic(i)
}
// getUnderlyingSlice converts Events to its underlying []Event
func (e Events) getUnderlyingSlice() []Event {
return e
}

// Common event types and attribute keys
Expand Down
17 changes: 17 additions & 0 deletions types/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,23 @@ func (s *eventsTestSuite) TestEventManagerTypedEvents() {
s.Require().Equal(hasAnimal.Animal.String(), response.Animal.String())
}

func (s *eventsTestSuite) TestIncreaseCapcity() {
// Ensure that appends still work after increase capacity is called.
// This does not check that the underlying capacity was increased,
// however this has been ensured via benchmarks.
em := sdk.NewEventManager()
e1 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))
e2 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar"))
a := sdk.Events{e1}
b := sdk.Events{e2}
em.EmitEvents(a)
em.IncreaseCapacity(1024)
em.EmitEvents(b)
s.Require().Equal(em.Events(), sdk.Events{e1, e2})
s.Require().Equal(em.Events(), sdk.Events{e1}.AppendEvent(sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar"))))
s.Require().Equal(em.Events(), sdk.Events{e1}.AppendEvents(sdk.Events{e2}))
}

func (s *eventsTestSuite) TestStringifyEvents() {
e := sdk.Events{
sdk.NewEvent("message", sdk.NewAttribute("sender", "foo")),
Expand Down
22 changes: 10 additions & 12 deletions x/bank/keeper/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,16 @@ func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAd
k.ak.SetAccount(ctx, k.ak.NewAccountWithAddress(ctx, toAddr))
}

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeTransfer,
sdk.NewAttribute(types.AttributeKeyRecipient, toAddr.String()),
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
),
})
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeTransfer,
sdk.NewAttribute(types.AttributeKeyRecipient, toAddr.String()),
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()),
))
ctx.EventManager().EmitEvent(sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
))

return nil
}
Expand Down

0 comments on commit a32faa9

Please sign in to comment.