...
1
2
3
4
5
6
7 package bsoncodec
8
9 import (
10 "reflect"
11 "sync"
12 "sync/atomic"
13 )
14
15
16
17 func init() {
18 if s := reflect.Kind(len(kindEncoderCache{}.entries)).String(); s != "kind27" {
19 panic("The capacity of kindEncoderCache is too small.\n" +
20 "This is due to a new type being added to reflect.Kind.")
21 }
22 }
23
24
25 var _ = (kindEncoderCache{}).entries[reflect.UnsafePointer]
26 var _ = (kindDecoderCache{}).entries[reflect.UnsafePointer]
27
28 type typeEncoderCache struct {
29 cache sync.Map
30 }
31
32 func (c *typeEncoderCache) Store(rt reflect.Type, enc ValueEncoder) {
33 c.cache.Store(rt, enc)
34 }
35
36 func (c *typeEncoderCache) Load(rt reflect.Type) (ValueEncoder, bool) {
37 if v, _ := c.cache.Load(rt); v != nil {
38 return v.(ValueEncoder), true
39 }
40 return nil, false
41 }
42
43 func (c *typeEncoderCache) LoadOrStore(rt reflect.Type, enc ValueEncoder) ValueEncoder {
44 if v, loaded := c.cache.LoadOrStore(rt, enc); loaded {
45 enc = v.(ValueEncoder)
46 }
47 return enc
48 }
49
50 func (c *typeEncoderCache) Clone() *typeEncoderCache {
51 cc := new(typeEncoderCache)
52 c.cache.Range(func(k, v interface{}) bool {
53 if k != nil && v != nil {
54 cc.cache.Store(k, v)
55 }
56 return true
57 })
58 return cc
59 }
60
61 type typeDecoderCache struct {
62 cache sync.Map
63 }
64
65 func (c *typeDecoderCache) Store(rt reflect.Type, dec ValueDecoder) {
66 c.cache.Store(rt, dec)
67 }
68
69 func (c *typeDecoderCache) Load(rt reflect.Type) (ValueDecoder, bool) {
70 if v, _ := c.cache.Load(rt); v != nil {
71 return v.(ValueDecoder), true
72 }
73 return nil, false
74 }
75
76 func (c *typeDecoderCache) LoadOrStore(rt reflect.Type, dec ValueDecoder) ValueDecoder {
77 if v, loaded := c.cache.LoadOrStore(rt, dec); loaded {
78 dec = v.(ValueDecoder)
79 }
80 return dec
81 }
82
83 func (c *typeDecoderCache) Clone() *typeDecoderCache {
84 cc := new(typeDecoderCache)
85 c.cache.Range(func(k, v interface{}) bool {
86 if k != nil && v != nil {
87 cc.cache.Store(k, v)
88 }
89 return true
90 })
91 return cc
92 }
93
94
95
96
97
98 type kindEncoderCacheEntry struct {
99 enc ValueEncoder
100 }
101
102 type kindEncoderCache struct {
103 entries [reflect.UnsafePointer + 1]atomic.Value
104 }
105
106 func (c *kindEncoderCache) Store(rt reflect.Kind, enc ValueEncoder) {
107 if enc != nil && rt < reflect.Kind(len(c.entries)) {
108 c.entries[rt].Store(&kindEncoderCacheEntry{enc: enc})
109 }
110 }
111
112 func (c *kindEncoderCache) Load(rt reflect.Kind) (ValueEncoder, bool) {
113 if rt < reflect.Kind(len(c.entries)) {
114 if ent, ok := c.entries[rt].Load().(*kindEncoderCacheEntry); ok {
115 return ent.enc, ent.enc != nil
116 }
117 }
118 return nil, false
119 }
120
121 func (c *kindEncoderCache) Clone() *kindEncoderCache {
122 cc := new(kindEncoderCache)
123 for i, v := range c.entries {
124 if val := v.Load(); val != nil {
125 cc.entries[i].Store(val)
126 }
127 }
128 return cc
129 }
130
131
132
133
134
135 type kindDecoderCacheEntry struct {
136 dec ValueDecoder
137 }
138
139 type kindDecoderCache struct {
140 entries [reflect.UnsafePointer + 1]atomic.Value
141 }
142
143 func (c *kindDecoderCache) Store(rt reflect.Kind, dec ValueDecoder) {
144 if rt < reflect.Kind(len(c.entries)) {
145 c.entries[rt].Store(&kindDecoderCacheEntry{dec: dec})
146 }
147 }
148
149 func (c *kindDecoderCache) Load(rt reflect.Kind) (ValueDecoder, bool) {
150 if rt < reflect.Kind(len(c.entries)) {
151 if ent, ok := c.entries[rt].Load().(*kindDecoderCacheEntry); ok {
152 return ent.dec, ent.dec != nil
153 }
154 }
155 return nil, false
156 }
157
158 func (c *kindDecoderCache) Clone() *kindDecoderCache {
159 cc := new(kindDecoderCache)
160 for i, v := range c.entries {
161 if val := v.Load(); val != nil {
162 cc.entries[i].Store(val)
163 }
164 }
165 return cc
166 }
167
View as plain text