-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserialization.go
More file actions
75 lines (61 loc) · 1.83 KB
/
Copy pathserialization.go
File metadata and controls
75 lines (61 loc) · 1.83 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
72
73
74
75
package cmap
// JSONCompatible 标记支持JSON序列化的接口
type JSONCompatible interface {
IsJSON() bool
}
// MarshalJSON JSON序列化
func (m *Map[K, V]) MarshalJSON() ([]byte, error) {
serializer := m.getJSONSerializer()
return m.MarshalWith(serializer)
}
// UnmarshalJSON JSON反序列化
func (m *Map[K, V]) UnmarshalJSON(data []byte) error {
serializer := m.getJSONSerializer()
return m.UnmarshalWith(data, serializer)
}
// getJSONSerializer 获取JSON序列化器,使用接口判断
func (m *Map[K, V]) getJSONSerializer() *SerializerFunc {
serializer := m.opts.Serializer
if serializer == nil {
return JsonSerializer()
}
// 如果实现了JSONCompatible接口,就直接使用
if _, ok := any(serializer).(JSONCompatible); ok {
return serializer
}
// 默认回退到标准JSON序列化器
return JsonSerializer()
}
// MarshalWith 使用指定序列化器进行序列化
func (m *Map[K, V]) MarshalWith(serializer *SerializerFunc) ([]byte, error) {
items := make([]Tuple[K, V], 0, m.Size())
for i := range m.shards {
m.shards[i].mu.RLock()
keys := m.shards[i].m.Keys()
for _, key := range keys {
value, _ := m.shards[i].m.Get(key)
items = append(items, Tuple[K, V]{Key: key, Value: value})
}
m.shards[i].mu.RUnlock()
}
data := SerializableData[K, V]{Items: items}
return serializer.Marshal(data)
}
// UnmarshalWith 使用指定序列化器进行反序列化
func (m *Map[K, V]) UnmarshalWith(data []byte, serializer *SerializerFunc) error {
var serializableData SerializableData[K, V]
if err := serializer.Unmarshal(data, &serializableData); err != nil {
return err
}
// 清空现有数据
m.Clear()
// 加载数据
for _, tuple := range serializableData.Items {
m.Put(tuple.Key, tuple.Value)
}
// 加载完成后标记为未修改
m.mu.Lock()
m.dirty = false
m.mu.Unlock()
return nil
}