-
Notifications
You must be signed in to change notification settings - Fork 6
/
cacheutils.go
61 lines (50 loc) · 2.03 KB
/
cacheutils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Package configcatcache holds utility functions for the SDK's caching.
package configcatcache
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"fmt"
"strconv"
"time"
)
const newLineByte byte = '\n'
// CacheSegmentsFromBytes deserializes a cache entry from a specific format used by the SDK.
func CacheSegmentsFromBytes(cacheBytes []byte) (fetchTime time.Time, eTag string, config []byte, err error) {
fetchTimeIndex := bytes.IndexByte(cacheBytes, newLineByte)
eTagIndex := bytes.IndexByte(cacheBytes[fetchTimeIndex+1:], newLineByte)
if fetchTimeIndex == -1 || eTagIndex == -1 {
return time.Time{}, "", nil, fmt.Errorf("number of values is fewer than expected")
}
fetchTimeBytes := cacheBytes[:fetchTimeIndex]
fetchTimeMs, err := strconv.ParseInt(string(fetchTimeBytes), 10, 64)
if err != nil {
return time.Time{}, "", nil, fmt.Errorf("invalid fetch time: %s. %v", fetchTimeBytes, err)
}
eTagBytes := cacheBytes[fetchTimeIndex+1 : fetchTimeIndex+eTagIndex+1]
if len(eTagBytes) == 0 {
return time.Time{}, "", nil, fmt.Errorf("empty eTag value")
}
configBytes := cacheBytes[eTagIndex+1+fetchTimeIndex+1:]
if len(configBytes) == 0 {
return time.Time{}, "", nil, fmt.Errorf("empty config JSON")
}
return time.UnixMilli(fetchTimeMs), string(eTagBytes), configBytes, nil
}
// CacheSegmentsToBytes serializes the input parameters to a specific format used for caching by the SDK.
func CacheSegmentsToBytes(fetchTime time.Time, eTag string, config []byte) []byte {
toCache := []byte(strconv.FormatInt(fetchTime.UnixMilli(), 10))
toCache = append(toCache, newLineByte)
toCache = append(toCache, eTag...)
toCache = append(toCache, newLineByte)
toCache = append(toCache, config...)
return toCache
}
const ConfigJSONCacheVersion = "v2"
const ConfigJSONName = "config_v5.json"
// ProduceCacheKey constructs a cache key from an SDK key used to identify a cache entry.
func ProduceCacheKey(sdkKey string) string {
h := sha1.New()
h.Write([]byte(sdkKey + "_" + ConfigJSONName + "_" + ConfigJSONCacheVersion))
return hex.EncodeToString(h.Sum(nil))
}