forked from sirnewton01/gojazz
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmeta.go
More file actions
159 lines (126 loc) · 3.43 KB
/
meta.go
File metadata and controls
159 lines (126 loc) · 3.43 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
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
package main
import (
"encoding/gob"
"os"
"path/filepath"
)
const (
metadataFileName = ".jazzmeta"
)
// TODO convert into a smaller object
type metaObject struct {
Path string
ItemId string
StateId string
LastModified int64
Size int64
Hash string
ComponentId string
}
type metaData struct {
pathMap map[string]metaObject
componentEtag map[string]string
isstream bool
ccmBaseUrl string
workspaceId string
projectName string
userId string
inited bool
storeMeta chan metaObject
sync chan int
}
func newMetaData() *metaData {
metadata := &metaData{}
metadata.pathMap = make(map[string]metaObject)
metadata.componentEtag = make(map[string]string)
metadata.inited = false
return metadata
}
func (metadata *metaData) load(path string) error {
file, err := os.Open(path)
if err == nil {
defer file.Close()
decoder := gob.NewDecoder(file)
err = decoder.Decode(&metadata.isstream)
err = decoder.Decode(&metadata.ccmBaseUrl)
err = decoder.Decode(&metadata.workspaceId)
err = decoder.Decode(&metadata.projectName)
err = decoder.Decode(&metadata.userId)
err = decoder.Decode(&metadata.pathMap)
err = decoder.Decode(&metadata.componentEtag)
}
return err
}
func (metadata *metaData) save(path string) error {
if metadata.inited {
// Synchronize first and then write out the metadata
metadata.sync <- 1
}
file, err := os.Create(path)
if err == nil {
defer file.Close()
encoder := gob.NewEncoder(file)
err = encoder.Encode(&metadata.isstream)
err = encoder.Encode(&metadata.ccmBaseUrl)
err = encoder.Encode(&metadata.workspaceId)
err = encoder.Encode(&metadata.projectName)
err = encoder.Encode(&metadata.userId)
err = encoder.Encode(&metadata.pathMap)
err = encoder.Encode(&metadata.componentEtag)
}
return err
}
func (metadata *metaData) initConcurrentWrite() {
metadata.storeMeta = make(chan metaObject)
metadata.sync = make(chan int)
metadata.inited = true
go func() {
for {
select {
case data := <-metadata.storeMeta:
metadata.pathMap[data.Path] = data
case <-metadata.sync:
// Shutdown after synchronizing
metadata.inited = false
return
}
}
}()
}
func (metadata *metaData) put(obj metaObject, sandboxpath string) {
if !metadata.inited {
panic("Metadata is not initialized for concurrent write, call initConcurentWrite first")
}
// Reduce the path of the metadata object using the sandbox path
// this will dramatically decrease the size of the metadata
relpath, err := filepath.Rel(sandboxpath, obj.Path)
if err != nil {
panic(err)
}
obj.Path = relpath
metadata.storeMeta <- obj
}
func (metadata *metaData) simplePut(obj metaObject, sandboxpath string) {
// Reduce the path of the metadata object using the sandbox path
// this will dramatically decrease the size of the metadata
relpath, err := filepath.Rel(sandboxpath, obj.Path)
if err != nil {
panic(err)
}
obj.Path = relpath
metadata.pathMap[relpath] = obj
}
func (metadata *metaData) get(path string, sandboxpath string) (metaObject, bool) {
// All metadata lookups are based on relative path
relpath, err := filepath.Rel(sandboxpath, path)
if err != nil {
panic(err)
}
meta, hit := metadata.pathMap[relpath]
// This may be an zero (empty) metadata object (ie. a miss on the metadata map)
// Don't do any manipulation of the path
if hit {
meta.Path = filepath.Join(sandboxpath, meta.Path)
}
return meta, hit
}