caching.go 1.51 KB
Newer Older
1 2
package blockstore

3
import (
4
	"context"
5 6
	"errors"

7
	metrics "gitlab.dms3.io/dms3/go-metrics-interface"
8 9
)

10
// CacheOpts wraps options for CachedBlockStore().
11 12
// Next to each option is it aproximate memory usage per unit
type CacheOpts struct {
13
	HasBloomFilterSize   int // 1 byte
14 15 16 17
	HasBloomFilterHashes int // No size, 7 is usually best, consult bloom papers
	HasARCCacheSize      int // 32 bytes
}

18
// DefaultCacheOpts returns a CacheOpts initialized with default values.
19 20
func DefaultCacheOpts() CacheOpts {
	return CacheOpts{
21
		HasBloomFilterSize:   512 << 10,
22
		HasBloomFilterHashes: 7,
23
		HasARCCacheSize:      64 << 10,
24 25
	}
}
26

27 28 29 30 31 32
// CachedBlockstore returns a blockstore wrapped in an ARCCache and
// then in a bloom filter cache, if the options indicate it.
func CachedBlockstore(
	ctx context.Context,
	bs Blockstore,
	opts CacheOpts) (cbs Blockstore, err error) {
33
	cbs = bs
34 35 36 37 38 39 40 41 42

	if opts.HasBloomFilterSize < 0 || opts.HasBloomFilterHashes < 0 ||
		opts.HasARCCacheSize < 0 {
		return nil, errors.New("all options for cache need to be greater than zero")
	}

	if opts.HasBloomFilterSize != 0 && opts.HasBloomFilterHashes == 0 {
		return nil, errors.New("bloom filter hash count can't be 0 when there is size set")
	}
43 44 45

	ctx = metrics.CtxSubScope(ctx, "bs.cache")

46
	if opts.HasARCCacheSize > 0 {
47
		cbs, err = newARCCachedBS(ctx, cbs, opts.HasARCCacheSize)
48
	}
49
	if opts.HasBloomFilterSize != 0 {
50
		// *8 because of bytes to bits conversion
51
		cbs, err = bloomCached(ctx, cbs, opts.HasBloomFilterSize*8, opts.HasBloomFilterHashes)
52
	}
53 54 55

	return cbs, err
}