-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: Add a map coins struct to speedup bank genesis (#15764)
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Marko <marbar3778@yahoo.com>
- Loading branch information
1 parent
0615387
commit 1903903
Showing
5 changed files
with
176 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package types | ||
|
||
// map coins is a map representation of sdk.Coins | ||
// intended solely for use in bulk additions. | ||
// All serialization and iteration should be done after conversion to sdk.Coins. | ||
type MapCoins map[string]Int | ||
|
||
func NewMapCoins(coins Coins) MapCoins { | ||
m := make(MapCoins, len(coins)) | ||
m.Add(coins...) | ||
return m | ||
} | ||
|
||
func (m MapCoins) Add(coins ...Coin) { | ||
for _, coin := range coins { | ||
existAmt, exists := m[coin.Denom] | ||
// TODO: Once int supports in-place arithmetic, switch this to be in-place. | ||
if exists { | ||
m[coin.Denom] = existAmt.Add(coin.Amount) | ||
} else { | ||
m[coin.Denom] = coin.Amount | ||
} | ||
} | ||
} | ||
|
||
func (m MapCoins) ToCoins() Coins { | ||
if len(m) == 0 { | ||
return Coins{} | ||
} | ||
coins := make(Coins, 0, len(m)) | ||
for denom, amount := range m { | ||
if amount.IsZero() { | ||
continue | ||
} | ||
coins = append(coins, NewCoin(denom, amount)) | ||
} | ||
if len(coins) == 0 { | ||
return Coins{} | ||
} | ||
coins.Sort() | ||
return coins | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package types_test | ||
|
||
import ( | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func (s *coinTestSuite) TestMapCoinsAdd() { | ||
cA0M0 := sdk.Coins{s.ca0, s.cm0} | ||
cA0M1 := sdk.Coins{s.ca0, s.cm1} | ||
cA1M1 := sdk.Coins{s.ca1, s.cm1} | ||
cases := []struct { | ||
name string | ||
inputOne sdk.Coins | ||
inputTwo sdk.Coins | ||
expected sdk.Coins | ||
msg string | ||
}{ | ||
{"adding two empty lists", s.emptyCoins, s.emptyCoins, s.emptyCoins, "empty, non list should be returned"}, | ||
{"empty list + set", s.emptyCoins, cA0M1, sdk.Coins{s.cm1}, "zero coins should be removed"}, | ||
{"empty list + set", s.emptyCoins, cA1M1, cA1M1, "zero + a_non_zero = a_non_zero"}, | ||
{"set + empty list", cA0M1, s.emptyCoins, sdk.Coins{s.cm1}, "zero coins should be removed"}, | ||
{"set + empty list", cA1M1, s.emptyCoins, cA1M1, "a_non_zero + zero = a_non_zero"}, | ||
{ | ||
"{1atom,1muon}+{1atom,1muon}", cA1M1, cA1M1, | ||
sdk.Coins{s.ca2, s.cm2}, | ||
"a + a = 2a", | ||
}, | ||
{ | ||
"{0atom,1muon}+{0atom,0muon}", cA0M1, cA0M0, | ||
sdk.Coins{s.cm1}, | ||
"zero coins should be removed", | ||
}, | ||
{ | ||
"{2atom}+{0muon}", | ||
sdk.Coins{s.ca2}, | ||
sdk.Coins{s.cm0}, | ||
sdk.Coins{s.ca2}, | ||
"zero coins should be removed", | ||
}, | ||
{ | ||
"{1atom}+{1atom,2muon}", | ||
sdk.Coins{s.ca1}, | ||
sdk.Coins{s.ca1, s.cm2}, | ||
sdk.Coins{s.ca2, s.cm2}, | ||
"should be correctly added", | ||
}, | ||
{ | ||
"{0atom,0muon}+{0atom,0muon}", cA0M0, cA0M0, s.emptyCoins, | ||
"sets with zero coins should return empty set", | ||
}, | ||
} | ||
|
||
for _, tc := range cases { | ||
expected := tc.inputOne.Add(tc.inputTwo...) | ||
m := sdk.NewMapCoins(tc.inputOne) | ||
m.Add(tc.inputTwo...) | ||
res := m.ToCoins() | ||
s.Require().True(res.IsValid()) | ||
require.Equal(s.T(), expected, res, tc.msg) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters