Skip to content

Commit

Permalink
[Chore] Add builder
Browse files Browse the repository at this point in the history
  • Loading branch information
maypok86 committed Oct 22, 2023
1 parent 3e3c944 commit a0fe64f
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 99 deletions.
82 changes: 82 additions & 0 deletions builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package otter

import "errors"

const (
illegalShardCount = -1
defaultShardCount = 128
defaultStatsEnabled = false
)

var (
ErrIllegalCapacity = errors.New("capacity should be positive")
ErrIllegalShardCount = errors.New("hashtable count should be positive")
)

type options[K comparable, V any] struct {
capacity int
shardCount int
statsEnabled bool
costFunc func(key K, value V) uint32
}

func (o *options[K, V]) validate() error {
if o.shardCount == illegalShardCount {
return ErrIllegalShardCount
}

return nil
}

func (o *options[K, V]) toConfig() Config[K, V] {
return Config[K, V]{
Capacity: o.capacity,
ShardCount: o.shardCount,
StatsEnabled: o.statsEnabled,
CostFunc: o.costFunc,
}
}

type Builder[K comparable, V any] struct {
options[K, V]
}

func NewBuilder[K comparable, V any](capacity int) (*Builder[K, V], error) {
if capacity <= 0 {
return nil, ErrIllegalCapacity
}

return &Builder[K, V]{
options: options[K, V]{
capacity: capacity,
shardCount: defaultShardCount,
statsEnabled: defaultStatsEnabled,
costFunc: func(key K, value V) uint32 {
return 1
},
},
}, nil
}

func (b *Builder[K, V]) ShardCount(shardCount int) *Builder[K, V] {
b.shardCount = shardCount
return b
}

func (b *Builder[K, V]) StatsEnabled(statsEnabled bool) *Builder[K, V] {
b.statsEnabled = statsEnabled
return b
}

func (b *Builder[K, V]) Cost(costFunc func(key K, value V) uint32) *Builder[K, V] {
b.costFunc = costFunc
return b
}

func (b *Builder[K, V]) Build() (*Cache[K, V], error) {
if err := b.validate(); err != nil {
return nil, err
}

return NewCache(b.toConfig()), nil
}
49 changes: 25 additions & 24 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ func zeroValue[V any]() V {
return zero
}

type Config[K comparable, V any] struct {
Capacity int
ShardCount int
StatsEnabled bool
CostFunc func(key K, value V) uint32
}

type Cache[K comparable, V any] struct {
shards []*hashtable.Map[K, V]
policy *s3fifo.Policy[K, V]
Expand All @@ -28,46 +35,39 @@ type Cache[K comparable, V any] struct {
writeBuffer *queue.MPSC[s3fifo.WriteItem[K, V]]
closeOnce sync.Once
hasher *hasher[K]
costFunc func(key K, value V) uint32
mask uint64
capacity int
}

func New[K comparable, V any](opts ...Option) (*Cache[K, V], error) {
o := defaultOptions()
for _, opt := range opts {
opt(o)
}

if err := o.validate(); err != nil {
return nil, err
}

shardCapacity := (o.capacity + o.shardCount - 1) / o.shardCount
shards := make([]*hashtable.Map[K, V], 0, o.shardCount)
readBuffers := make([]*lossy.Buffer[*node.Node[K, V]], 0, o.shardCount)
for i := 0; i < o.shardCount; i++ {
func NewCache[K comparable, V any](c Config[K, V]) *Cache[K, V] {
shardCapacity := (c.Capacity + c.ShardCount - 1) / c.ShardCount
shards := make([]*hashtable.Map[K, V], 0, c.ShardCount)
readBuffers := make([]*lossy.Buffer[*node.Node[K, V]], 0, c.ShardCount)
for i := 0; i < c.ShardCount; i++ {
shards = append(shards, hashtable.New[K, V](hashtable.WithNodeCount[K](shardCapacity)))
readBuffers = append(readBuffers, lossy.New[*node.Node[K, V]]())
}

c := &Cache[K, V]{
cache := &Cache[K, V]{
shards: shards,
readBuffers: readBuffers,
writeBuffer: queue.NewMPSC[s3fifo.WriteItem[K, V]](128 * int(xmath.RoundUpPowerOf2(xruntime.Parallelism()))),
hasher: newHasher[K](),
mask: uint64(o.shardCount - 1),
capacity: o.capacity,
mask: uint64(c.ShardCount - 1),
costFunc: c.CostFunc,
capacity: c.Capacity,
}

c.policy = s3fifo.NewPolicy[K, V](uint32(o.capacity))
if o.statsEnabled {
c.stats = stats.New()
cache.policy = s3fifo.NewPolicy[K, V](uint32(c.Capacity))
if c.StatsEnabled {
cache.stats = stats.New()
}

unixtime.Start()
go c.process()
go cache.process()

return c, nil
return cache
}

func (c *Cache[K, V]) getShardIdx(key K) int {
Expand Down Expand Up @@ -117,12 +117,13 @@ func (c *Cache[K, V]) Set(key K, value V) {
}

func (c *Cache[K, V]) SetWithTTL(key K, value V, ttl time.Duration) {
expiration := unixtime.Now() + uint64(ttl/time.Second)
ttl = (ttl + time.Second - 1) / time.Second
expiration := unixtime.Now() + uint64(ttl)
c.set(key, value, expiration)
}

func (c *Cache[K, V]) set(key K, value V, expiration uint64) {
cost := uint32(1)
cost := c.costFunc(key, value)
if cost >= c.policy.MaxAvailableCost() {
return
}
Expand Down
75 changes: 0 additions & 75 deletions option.go

This file was deleted.

0 comments on commit a0fe64f

Please sign in to comment.