Skip to content

Commit

Permalink
Merge branch 'dev' into version-bump-v1.10.6
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph committed Aug 1, 2023
2 parents cd86210 + 6e97e33 commit aadef46
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 33 deletions.
3 changes: 3 additions & 0 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type Cacher[K comparable, V any] interface {
// Flush removes all entries from the cache
Flush()

// Returns the number of elements currently in the cache
Len() int

// Returns fraction of cache currently filled (0 --> 1)
PortionFilled() float64
}
Expand Down
4 changes: 4 additions & 0 deletions cache/empty_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ func (*Empty[K, _]) Evict(K) {}

func (*Empty[_, _]) Flush() {}

func (*Empty[_, _]) Len() int {
return 0
}

func (*Empty[_, _]) PortionFilled() float64 {
return 0
}
16 changes: 15 additions & 1 deletion cache/lru_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ func (c *LRU[_, _]) Flush() {
c.flush()
}

func (c *LRU[_, _]) Len() int {
c.lock.Lock()
defer c.lock.Unlock()

return c.len()
}

func (c *LRU[_, _]) PortionFilled() float64 {
c.lock.Lock()
defer c.lock.Unlock()
Expand Down Expand Up @@ -88,8 +95,15 @@ func (c *LRU[K, V]) flush() {
c.elements = linkedhashmap.New[K, V]()
}

func (c *LRU[_, _]) len() int {
if c.elements == nil {
return 0
}
return c.elements.Len()
}

func (c *LRU[_, _]) portionFilled() float64 {
return float64(c.elements.Len()) / float64(c.Size)
return float64(c.len()) / float64(c.Size)
}

// Initializes [c.elements] if it's nil.
Expand Down
11 changes: 11 additions & 0 deletions cache/lru_sized_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ func (c *sizedLRU[K, V]) Flush() {
c.flush()
}

func (c *sizedLRU[_, _]) Len() int {
c.lock.Lock()
defer c.lock.Unlock()

return c.len()
}

func (c *sizedLRU[_, _]) PortionFilled() float64 {
c.lock.Lock()
defer c.lock.Unlock()
Expand Down Expand Up @@ -110,6 +117,10 @@ func (c *sizedLRU[K, V]) flush() {
c.currentSize = 0
}

func (c *sizedLRU[_, _]) len() int {
return c.elements.Len()
}

func (c *sizedLRU[_, _]) portionFilled() float64 {
return float64(c.currentSize) / float64(c.maxSize)
}
3 changes: 3 additions & 0 deletions cache/metercacher/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (c *Cache[K, V]) Put(key K, value V) {
c.Cacher.Put(key, value)
end := c.clock.Time()
c.put.Observe(float64(end.Sub(start)))
c.len.Set(float64(c.Cacher.Len()))
c.portionFilled.Set(c.Cacher.PortionFilled())
}

Expand All @@ -52,10 +53,12 @@ func (c *Cache[K, V]) Get(key K) (V, bool) {

func (c *Cache[K, _]) Evict(key K) {
c.Cacher.Evict(key)
c.len.Set(float64(c.Cacher.Len()))
c.portionFilled.Set(c.Cacher.PortionFilled())
}

func (c *Cache[_, _]) Flush() {
c.Cacher.Flush()
c.len.Set(float64(c.Cacher.Len()))
c.portionFilled.Set(c.Cacher.PortionFilled())
}
16 changes: 12 additions & 4 deletions cache/metercacher/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ func newCounterMetric(namespace, name string, reg prometheus.Registerer, errs *w
}

type metrics struct {
get,
put metric.Averager
get metric.Averager
put metric.Averager
len prometheus.Gauge
portionFilled prometheus.Gauge
hit,
miss prometheus.Counter
hit prometheus.Counter
miss prometheus.Counter
}

func (m *metrics) Initialize(
Expand All @@ -47,6 +48,13 @@ func (m *metrics) Initialize(
errs := wrappers.Errs{}
m.get = newAveragerMetric(namespace, "get", reg, &errs)
m.put = newAveragerMetric(namespace, "put", reg, &errs)
m.len = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: namespace,
Name: "len",
Help: "number of entries",
},
)
m.portionFilled = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: namespace,
Expand Down
8 changes: 8 additions & 0 deletions cache/test_cacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,16 @@ func TestEviction(t *testing.T, cache Cacher[ids.ID, int64]) {
expectedValue2 := int64(2)
expectedValue3 := int64(3)

require.Zero(cache.Len())

cache.Put(id1, expectedValue1)

require.Equal(1, cache.Len())

cache.Put(id2, expectedValue2)

require.Equal(2, cache.Len())

val, found := cache.Get(id1)
require.True(found)
require.Equal(expectedValue1, val)
Expand All @@ -87,6 +94,7 @@ func TestEviction(t *testing.T, cache Cacher[ids.ID, int64]) {
require.False(found)

cache.Put(id3, expectedValue3)
require.Equal(2, cache.Len())

_, found = cache.Get(id1)
require.False(found)
Expand Down
13 changes: 11 additions & 2 deletions snow/engine/snowman/transitive.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,25 @@ import (
"github.com/ava-labs/avalanchego/snow/events"
"github.com/ava-labs/avalanchego/snow/validators"
"github.com/ava-labs/avalanchego/utils/bag"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/utils/wrappers"
)

const nonVerifiedCacheSize = 128
const nonVerifiedCacheSize = 128 * units.MiB

var _ Engine = (*Transitive)(nil)

func New(config Config) (Engine, error) {
return newTransitive(config)
}

func cachedBlockSize(_ ids.ID, blk snowman.Block) int {
return ids.IDLen + len(blk.Bytes()) + constants.PointerOverhead
}

// Transitive implements the Engine interface by attempting to fetch all
// Transitive dependencies.
type Transitive struct {
Expand Down Expand Up @@ -92,7 +98,10 @@ func newTransitive(config Config) (*Transitive, error) {
nonVerifiedCache, err := metercacher.New[ids.ID, snowman.Block](
"non_verified_cache",
config.Ctx.Registerer,
&cache.LRU[ids.ID, snowman.Block]{Size: nonVerifiedCacheSize},
cache.NewSizedLRU[ids.ID, snowman.Block](
nonVerifiedCacheSize,
cachedBlockSize,
),
)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions utils/constants/memory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package constants

// PointerOverhead is used to approximate the memory footprint from allocating a
// pointer.
const PointerOverhead = 8
43 changes: 35 additions & 8 deletions vms/components/chain/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,17 @@ import (
"github.com/ava-labs/avalanchego/snow/choices"
"github.com/ava-labs/avalanchego/snow/consensus/snowman"
"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
"github.com/ava-labs/avalanchego/utils/constants"
)

func cachedBlockSize(_ ids.ID, bw *BlockWrapper) int {
return ids.IDLen + len(bw.Bytes()) + 2*constants.PointerOverhead
}

func cachedBlockBytesSize(blockBytes string, _ ids.ID) int {
return len(blockBytes) + ids.IDLen
}

// State implements an efficient caching layer used to wrap a VM
// implementation.
type State struct {
Expand Down Expand Up @@ -138,11 +147,20 @@ func (s *State) initialize(config *Config) {

func NewState(config *Config) *State {
c := &State{
verifiedBlocks: make(map[ids.ID]*BlockWrapper),
decidedBlocks: &cache.LRU[ids.ID, *BlockWrapper]{Size: config.DecidedCacheSize},
missingBlocks: &cache.LRU[ids.ID, struct{}]{Size: config.MissingCacheSize},
unverifiedBlocks: &cache.LRU[ids.ID, *BlockWrapper]{Size: config.UnverifiedCacheSize},
bytesToIDCache: &cache.LRU[string, ids.ID]{Size: config.BytesToIDCacheSize},
verifiedBlocks: make(map[ids.ID]*BlockWrapper),
decidedBlocks: cache.NewSizedLRU[ids.ID, *BlockWrapper](
config.DecidedCacheSize,
cachedBlockSize,
),
missingBlocks: &cache.LRU[ids.ID, struct{}]{Size: config.MissingCacheSize},
unverifiedBlocks: cache.NewSizedLRU[ids.ID, *BlockWrapper](
config.UnverifiedCacheSize,
cachedBlockSize,
),
bytesToIDCache: cache.NewSizedLRU[string, ids.ID](
config.BytesToIDCacheSize,
cachedBlockBytesSize,
),
}
c.initialize(config)
return c
Expand All @@ -155,7 +173,10 @@ func NewMeteredState(
decidedCache, err := metercacher.New[ids.ID, *BlockWrapper](
"decided_cache",
registerer,
&cache.LRU[ids.ID, *BlockWrapper]{Size: config.DecidedCacheSize},
cache.NewSizedLRU[ids.ID, *BlockWrapper](
config.DecidedCacheSize,
cachedBlockSize,
),
)
if err != nil {
return nil, err
Expand All @@ -171,15 +192,21 @@ func NewMeteredState(
unverifiedCache, err := metercacher.New[ids.ID, *BlockWrapper](
"unverified_cache",
registerer,
&cache.LRU[ids.ID, *BlockWrapper]{Size: config.UnverifiedCacheSize},
cache.NewSizedLRU[ids.ID, *BlockWrapper](
config.UnverifiedCacheSize,
cachedBlockSize,
),
)
if err != nil {
return nil, err
}
bytesToIDCache, err := metercacher.New[string, ids.ID](
"bytes_to_id_cache",
registerer,
&cache.LRU[string, ids.ID]{Size: config.BytesToIDCacheSize},
cache.NewSizedLRU[string, ids.ID](
config.BytesToIDCacheSize,
cachedBlockBytesSize,
),
)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion vms/components/chain/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ func TestStateBytesToIDCache(t *testing.T) {
DecidedCacheSize: 0,
MissingCacheSize: 0,
UnverifiedCacheSize: 0,
BytesToIDCacheSize: 1,
BytesToIDCacheSize: 1 + ids.IDLen, // Size of one block
LastAcceptedBlock: genesisBlock,
GetBlock: getBlock,
UnmarshalBlock: parseBlock,
Expand Down
14 changes: 6 additions & 8 deletions vms/platformvm/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import (
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
)

const pointerOverhead = wrappers.LongLen

var (
_ State = (*state)(nil)

Expand Down Expand Up @@ -383,23 +381,23 @@ type txAndStatus struct {

func txSize(_ ids.ID, tx *txs.Tx) int {
if tx == nil {
return ids.IDLen + pointerOverhead
return ids.IDLen + constants.PointerOverhead
}
return ids.IDLen + len(tx.Bytes()) + pointerOverhead
return ids.IDLen + len(tx.Bytes()) + constants.PointerOverhead
}

func txAndStatusSize(_ ids.ID, t *txAndStatus) int {
if t == nil {
return ids.IDLen + pointerOverhead
return ids.IDLen + constants.PointerOverhead
}
return ids.IDLen + len(t.tx.Bytes()) + wrappers.IntLen + pointerOverhead
return ids.IDLen + len(t.tx.Bytes()) + wrappers.IntLen + 2*constants.PointerOverhead
}

func blockSize(_ ids.ID, blk blocks.Block) int {
if blk == nil {
return ids.IDLen + pointerOverhead
return ids.IDLen + constants.PointerOverhead
}
return ids.IDLen + len(blk.Bytes()) + pointerOverhead
return ids.IDLen + len(blk.Bytes()) + constants.PointerOverhead
}

func New(
Expand Down
24 changes: 20 additions & 4 deletions vms/proposervm/state/block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import (
"github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow/choices"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/utils/wrappers"
"github.com/ava-labs/avalanchego/vms/proposervm/block"
)

const blockCacheSize = 8192
const blockCacheSize = 256 * units.MiB

var (
errBlockWrongVersion = errors.New("wrong version")
Expand Down Expand Up @@ -45,18 +48,31 @@ type blockWrapper struct {
block block.Block
}

func cachedBlockSize(_ ids.ID, bw *blockWrapper) int {
if bw == nil {
return ids.IDLen + constants.PointerOverhead
}
return ids.IDLen + len(bw.Block) + wrappers.IntLen + 2*constants.PointerOverhead
}

func NewBlockState(db database.Database) BlockState {
return &blockState{
blkCache: &cache.LRU[ids.ID, *blockWrapper]{Size: blockCacheSize},
db: db,
blkCache: cache.NewSizedLRU[ids.ID, *blockWrapper](
blockCacheSize,
cachedBlockSize,
),
db: db,
}
}

func NewMeteredBlockState(db database.Database, namespace string, metrics prometheus.Registerer) (BlockState, error) {
blkCache, err := metercacher.New[ids.ID, *blockWrapper](
fmt.Sprintf("%s_block_cache", namespace),
metrics,
&cache.LRU[ids.ID, *blockWrapper]{Size: blockCacheSize},
cache.NewSizedLRU[ids.ID, *blockWrapper](
blockCacheSize,
cachedBlockSize,
),
)

return &blockState{
Expand Down
Loading

0 comments on commit aadef46

Please sign in to comment.