-
Notifications
You must be signed in to change notification settings - Fork 0
/
image.go
101 lines (82 loc) · 2.16 KB
/
image.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
package main
import (
"os"
"time"
)
type Image struct {
Path string `json:"-"`
Driver string `json:"driver"`
Category string `json:"category"`
Group string `json:"group"`
Name string `json:"name"`
Link string `json:"link"`
ModTime time.Time `json:"mod_time"`
}
func (i *Image) Data() (ReadSeekCloser, error) {
return os.Open(i.Path)
}
func (i *Image) Endpoint() string {
s := "/" + i.Driver
if i.Category != "" {
s += "/" + i.Category
}
return s + "/" + i.Name
}
// Tree offers a hierarchical way of organizing images by their driver, category
// and group. The driver, category, and group of an image are used as the key
// under which an image would be stored, if they are not empty.
//
// Each time an image is stored in a tree, a new sub-tree may be created under
// which the image is actually stored. For example, if an image has the driver
// of "qemu", but not category or group, then it will be stored under a tree
// named "qemu". If an image has no driver, category or group, then it is
// stored in the root tree, that is, the top-level.
type Tree struct {
name string
order []string
images []*Image
children map[string]*Tree
}
func (t *Tree) get(key string) *Tree {
if t.children == nil {
t.children = make(map[string]*Tree)
}
t2, ok := t.children[key]
if !ok {
t.order = append(t.order, key)
t2 = &Tree{name: key}
t.children[key] = t2
}
return t2
}
func (t *Tree) put(img *Image) {
t.images = append(t.images, img)
}
func (t *Tree) Put(img *Image) {
root := t
for _, key := range []string{img.Driver, img.Category, img.Group} {
if key == "" {
break
}
root = root.get(key)
}
root.put(img)
}
func (t *Tree) Walk(visit func(string, []*Image)) {
visit(t.name, t.images)
for _, key := range t.order {
if t2, ok := t.children[key]; ok {
t2.Walk(visit)
}
}
}
func (t *Tree) Name() string { return t.name }
func (t *Tree) Images() []*Image { return t.images }
func (t *Tree) Children() []*Tree {
tt := make([]*Tree, 0, len(t.children))
for _, name := range t.order {
tt = append(tt, t.children[name])
}
return tt
}
func (t *Tree) HasChildren() bool { return len(t.children) > 0 }