...
1
16
17 package runtime
18
19 import (
20 "context"
21 "fmt"
22 "sync"
23
24 "github.com/containerd/containerd/errdefs"
25 "github.com/containerd/containerd/namespaces"
26 )
27
28 type object interface {
29 ID() string
30 }
31
32
33 type NSMap[T object] struct {
34 mu sync.Mutex
35 objects map[string]map[string]T
36 }
37
38
39 func NewNSMap[T object]() *NSMap[T] {
40 return &NSMap[T]{
41 objects: make(map[string]map[string]T),
42 }
43 }
44
45
46 func (m *NSMap[T]) Get(ctx context.Context, id string) (T, error) {
47 m.mu.Lock()
48 defer m.mu.Unlock()
49 namespace, err := namespaces.NamespaceRequired(ctx)
50 var t T
51 if err != nil {
52 return t, err
53 }
54 tasks, ok := m.objects[namespace]
55 if !ok {
56 return t, errdefs.ErrNotFound
57 }
58 t, ok = tasks[id]
59 if !ok {
60 return t, errdefs.ErrNotFound
61 }
62 return t, nil
63 }
64
65
66 func (m *NSMap[T]) GetAll(ctx context.Context, noNS bool) ([]T, error) {
67 m.mu.Lock()
68 defer m.mu.Unlock()
69 var o []T
70 if noNS {
71 for ns := range m.objects {
72 for _, t := range m.objects[ns] {
73 o = append(o, t)
74 }
75 }
76 return o, nil
77 }
78 namespace, err := namespaces.NamespaceRequired(ctx)
79 if err != nil {
80 return nil, err
81 }
82 tasks, ok := m.objects[namespace]
83 if !ok {
84 return o, nil
85 }
86 for _, t := range tasks {
87 o = append(o, t)
88 }
89 return o, nil
90 }
91
92
93 func (m *NSMap[T]) Add(ctx context.Context, t T) error {
94 namespace, err := namespaces.NamespaceRequired(ctx)
95 if err != nil {
96 return err
97 }
98 return m.AddWithNamespace(namespace, t)
99 }
100
101
102 func (m *NSMap[T]) AddWithNamespace(namespace string, t T) error {
103 m.mu.Lock()
104 defer m.mu.Unlock()
105
106 id := t.ID()
107 if _, ok := m.objects[namespace]; !ok {
108 m.objects[namespace] = make(map[string]T)
109 }
110 if _, ok := m.objects[namespace][id]; ok {
111 return fmt.Errorf("%s: %w", id, errdefs.ErrAlreadyExists)
112 }
113 m.objects[namespace][id] = t
114 return nil
115 }
116
117
118 func (m *NSMap[T]) Delete(ctx context.Context, id string) {
119 m.mu.Lock()
120 defer m.mu.Unlock()
121 namespace, err := namespaces.NamespaceRequired(ctx)
122 if err != nil {
123 return
124 }
125 tasks, ok := m.objects[namespace]
126 if ok {
127 delete(tasks, id)
128 }
129 }
130
131 func (m *NSMap[T]) IsEmpty() bool {
132 m.mu.Lock()
133 defer m.mu.Unlock()
134
135 for ns := range m.objects {
136 if len(m.objects[ns]) > 0 {
137 return false
138 }
139 }
140
141 return true
142 }
143
View as plain text