This repository was archived by the owner on Dec 27, 2024. It is now read-only.
forked from sajari/word2vec
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.go
More file actions
71 lines (62 loc) · 1.25 KB
/
cache.go
File metadata and controls
71 lines (62 loc) · 1.25 KB
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
62
63
64
65
66
67
68
69
70
71
package word2vec
import (
"crypto/sha1"
"sort"
"strconv"
)
// NewCache returns a Coser which will cache repeated calls to the Cos method,
// particularly useful when using Client.
func NewCache(c Coser) Coser {
return &cache{
Coser: c,
cache: make(map[string]float32),
errCache: make(map[string]error),
}
}
type cache struct {
Coser
errCache map[string]error
cache map[string]float32
}
func hashExpr(x Expr) string {
list := make([]string, 0, len(x))
for k := range x {
list = append(list, k)
}
sort.Strings(list)
h := sha1.New()
for _, w := range list {
h.Write([]byte(w))
h.Write([]byte(strconv.FormatFloat(float64(x[w]), 'f', -1, 64)))
}
return string(h.Sum(nil))
}
// Cos implements Coser.
func (c *cache) Cos(x, y Expr) (float32, error) {
xh := hashExpr(x)
if err, ok := c.errCache[xh]; ok {
return 0, err
}
yh := hashExpr(y)
if err, ok := c.errCache[yh]; ok {
return 0, err
}
if f, ok := c.cache[xh+yh]; ok {
return f, nil
}
f, err := c.Coser.Cos(x, y)
if err != nil {
if errNotFound, ok := err.(NotFoundError); ok {
w := errNotFound.Word
if _, ok := x[w]; ok {
c.errCache[xh] = err
}
if _, ok := y[w]; ok {
c.errCache[yh] = err
}
}
return 0, err
}
c.cache[xh+yh] = f
return f, nil
}