1package libkb
2
3import (
4	"encoding/hex"
5
6	lru "github.com/hashicorp/golang-lru"
7	jsonw "github.com/keybase/go-jsonw"
8)
9
10type PayloadCache struct {
11	Contextified
12	cache *lru.Cache
13}
14
15func NewPayloadCache(g *GlobalContext, maxNumElements int) *PayloadCache {
16	c, err := lru.New(maxNumElements)
17	if err != nil {
18		g.Log.Warning("failed to create PayloadCache LRU: %s", err)
19		c = nil
20	}
21
22	return &PayloadCache{
23		Contextified: NewContextified(g),
24		cache:        c,
25	}
26}
27
28func (p *PayloadCache) GetOrPrime(link *ChainLink) (*jsonw.Wrapper, error) {
29	// check if failed to create cache in NewPayloadCache
30	if p.cache == nil {
31		p.G().Log.Debug("PayloadCache no LRU, unmarshal for %x", link.unpacked.payloadHash)
32		payload, err := link.unpacked.Payload()
33		if err != nil {
34			return nil, err
35		}
36		return jsonw.Unmarshal(payload)
37	}
38
39	key := hex.EncodeToString(link.unpacked.payloadHash)
40
41	obj, ok := p.cache.Get(key)
42	if ok {
43		jw, ok := obj.(*jsonw.Wrapper)
44		if ok {
45			return jw, nil
46		}
47	}
48
49	payload, err := link.unpacked.Payload()
50	if err != nil {
51		return nil, err
52	}
53
54	jw, err := jsonw.Unmarshal(payload)
55	if err != nil {
56		return nil, err
57	}
58
59	p.cache.Add(key, jw)
60
61	return jw, nil
62}
63