forked from moriyoshi/s3-sftp-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
phantom_object_map.go
167 lines (144 loc) · 3.46 KB
/
phantom_object_map.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package main
import (
"sync"
"time"
)
type PhantomObjectInfo struct {
Key Path
LastModified time.Time
Size int64
Opaque interface{}
Mtx sync.Mutex
}
func (info *PhantomObjectInfo) GetOne() PhantomObjectInfo {
info.Mtx.Lock()
defer info.Mtx.Unlock()
return *info
}
func (info *PhantomObjectInfo) setKey(v Path) {
info.Mtx.Lock()
defer info.Mtx.Unlock()
info.Key = v
}
func (info *PhantomObjectInfo) SetLastModified(v time.Time) {
info.Mtx.Lock()
defer info.Mtx.Unlock()
info.LastModified = v
}
func (info *PhantomObjectInfo) SetSize(v int64) {
info.Mtx.Lock()
defer info.Mtx.Unlock()
info.Size = v
}
type phantomObjectInfoMap map[string]*PhantomObjectInfo
type PhantomObjectMap struct {
perPrefixObjects map[string]phantomObjectInfoMap
ptrToPOIMMapMap map[*PhantomObjectInfo]phantomObjectInfoMap
mtx sync.Mutex
}
func (pom *PhantomObjectMap) add(info *PhantomObjectInfo) bool {
prefix := info.Key.Prefix().String()
m := pom.perPrefixObjects[prefix]
if m == nil {
m = phantomObjectInfoMap{}
pom.perPrefixObjects[prefix] = m
}
prevInfo := m[info.Key.Base()]
m[info.Key.Base()] = info
pom.ptrToPOIMMapMap[info] = m
if prevInfo != nil {
delete(pom.ptrToPOIMMapMap, prevInfo)
}
return prevInfo == nil
}
func (pom *PhantomObjectMap) Add(info *PhantomObjectInfo) bool {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return pom.add(info)
}
func (pom *PhantomObjectMap) remove(key Path) *PhantomObjectInfo {
prefix := key.Prefix().String()
m := pom.perPrefixObjects[prefix]
if m == nil {
return nil
}
info := m[key.Base()]
if info == nil {
return nil
}
delete(m, key.Base())
if len(m) == 0 {
delete(pom.perPrefixObjects, prefix)
}
delete(pom.ptrToPOIMMapMap, info)
return info
}
func (pom *PhantomObjectMap) Remove(key Path) *PhantomObjectInfo {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return pom.remove(key)
}
func (pom *PhantomObjectMap) removeByInfoPtr(info *PhantomObjectInfo) bool {
m := pom.ptrToPOIMMapMap[info]
if m == nil {
return false
}
delete(m, info.Key.Base())
if len(m) == 0 {
delete(pom.perPrefixObjects, info.Key.Prefix().String())
}
delete(pom.ptrToPOIMMapMap, info)
return true
}
func (pom *PhantomObjectMap) RemoveByInfoPtr(info *PhantomObjectInfo) bool {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return pom.removeByInfoPtr(info)
}
func (pom *PhantomObjectMap) rename(old, new Path) bool {
info := pom.remove(old)
if info == nil {
return false
}
info.setKey(new)
pom.add(info)
return true
}
func (pom *PhantomObjectMap) Rename(old, new Path) bool {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return pom.rename(old, new)
}
func (pom *PhantomObjectMap) get(p Path) *PhantomObjectInfo {
m := pom.perPrefixObjects[p.Prefix().String()]
if m == nil {
return nil
}
return m[p.Base()]
}
func (pom *PhantomObjectMap) Get(p Path) *PhantomObjectInfo {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return pom.get(p)
}
func (pom *PhantomObjectMap) List(p Path) []*PhantomObjectInfo {
pom.mtx.Lock()
defer pom.mtx.Unlock()
m := pom.perPrefixObjects[p.String()]
retval := make([]*PhantomObjectInfo, 0, len(m))
for _, info := range m {
retval = append(retval, info)
}
return retval
}
func (pom *PhantomObjectMap) Size() int {
pom.mtx.Lock()
defer pom.mtx.Unlock()
return len(pom.ptrToPOIMMapMap)
}
func NewPhantomObjectMap() *PhantomObjectMap {
return &PhantomObjectMap{
perPrefixObjects: map[string]phantomObjectInfoMap{},
ptrToPOIMMapMap: map[*PhantomObjectInfo]phantomObjectInfoMap{},
}
}