Skip to content

Commit d7b6f8e

Browse files
fix: graph.Memory should use digest as map key (#1095)
Should fix #1093 Signed-off-by: Xiaoxuan Wang <wangxiaoxuan119@gmail.com>
1 parent bba6458 commit d7b6f8e

2 files changed

Lines changed: 106 additions & 125 deletions

File tree

internal/graph/memory.go

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"oras.land/oras-go/v2/content"
2626
"oras.land/oras-go/v2/errdef"
2727
"oras.land/oras-go/v2/internal/container/set"
28-
"oras.land/oras-go/v2/internal/descriptor"
2928
"oras.land/oras-go/v2/internal/status"
3029
"oras.land/oras-go/v2/internal/syncutil"
3130
)
@@ -34,34 +33,34 @@ import (
3433
type Memory struct {
3534
// nodes has the following properties and behaviors:
3635
// 1. a node exists in Memory.nodes if and only if it exists in the memory
37-
// 2. Memory.nodes saves the ocispec.Descriptor map keys, which are used by
36+
// 2. Memory.nodes saves the ocispec.Descriptor indexed by digest, which are used by
3837
// the other fields.
39-
nodes map[descriptor.Descriptor]ocispec.Descriptor
38+
nodes map[digest.Digest]ocispec.Descriptor
4039

4140
// predecessors has the following properties and behaviors:
4241
// 1. a node exists in Memory.predecessors if it has at least one predecessor
4342
// in the memory, regardless of whether or not the node itself exists in
4443
// the memory.
4544
// 2. a node does not exist in Memory.predecessors, if it doesn't have any predecessors
4645
// in the memory.
47-
predecessors map[descriptor.Descriptor]set.Set[descriptor.Descriptor]
46+
predecessors map[digest.Digest]set.Set[digest.Digest]
4847

4948
// successors has the following properties and behaviors:
5049
// 1. a node exists in Memory.successors if and only if it exists in the memory.
5150
// 2. a node's entry in Memory.successors is always consistent with the actual
5251
// content of the node, regardless of whether or not each successor exists
5352
// in the memory.
54-
successors map[descriptor.Descriptor]set.Set[descriptor.Descriptor]
53+
successors map[digest.Digest]set.Set[digest.Digest]
5554

5655
lock sync.RWMutex
5756
}
5857

5958
// NewMemory creates a new memory PredecessorFinder.
6059
func NewMemory() *Memory {
6160
return &Memory{
62-
nodes: make(map[descriptor.Descriptor]ocispec.Descriptor),
63-
predecessors: make(map[descriptor.Descriptor]set.Set[descriptor.Descriptor]),
64-
successors: make(map[descriptor.Descriptor]set.Set[descriptor.Descriptor]),
61+
nodes: make(map[digest.Digest]ocispec.Descriptor),
62+
predecessors: make(map[digest.Digest]set.Set[digest.Digest]),
63+
successors: make(map[digest.Digest]set.Set[digest.Digest]),
6564
}
6665
}
6766

@@ -108,14 +107,13 @@ func (m *Memory) Predecessors(_ context.Context, node ocispec.Descriptor) ([]oci
108107
m.lock.RLock()
109108
defer m.lock.RUnlock()
110109

111-
key := descriptor.FromOCI(node)
112-
set, exists := m.predecessors[key]
110+
set, exists := m.predecessors[node.Digest]
113111
if !exists {
114112
return nil, nil
115113
}
116114
var res []ocispec.Descriptor
117-
for k := range set {
118-
res = append(res, m.nodes[k])
115+
for digest := range set {
116+
res = append(res, m.nodes[digest])
119117
}
120118
return res, nil
121119
}
@@ -126,25 +124,24 @@ func (m *Memory) Remove(node ocispec.Descriptor) []ocispec.Descriptor {
126124
m.lock.Lock()
127125
defer m.lock.Unlock()
128126

129-
nodeKey := descriptor.FromOCI(node)
130127
var danglings []ocispec.Descriptor
131128
// remove the node from its successors' predecessor list
132-
for successorKey := range m.successors[nodeKey] {
133-
predecessorEntry := m.predecessors[successorKey]
134-
predecessorEntry.Delete(nodeKey)
129+
for successorDigest := range m.successors[node.Digest] {
130+
predecessorEntry := m.predecessors[successorDigest]
131+
predecessorEntry.Delete(node.Digest)
135132

136133
// if none of the predecessors of the node still exists, we remove the
137134
// predecessors entry and return it as a dangling node. Otherwise, we do
138135
// not remove the entry.
139136
if len(predecessorEntry) == 0 {
140-
delete(m.predecessors, successorKey)
141-
if _, exists := m.nodes[successorKey]; exists {
142-
danglings = append(danglings, m.nodes[successorKey])
137+
delete(m.predecessors, successorDigest)
138+
if _, exists := m.nodes[successorDigest]; exists {
139+
danglings = append(danglings, m.nodes[successorDigest])
143140
}
144141
}
145142
}
146-
delete(m.successors, nodeKey)
147-
delete(m.nodes, nodeKey)
143+
delete(m.successors, node.Digest)
144+
delete(m.nodes, node.Digest)
148145
return danglings
149146
}
150147

@@ -154,8 +151,8 @@ func (m *Memory) DigestSet() set.Set[digest.Digest] {
154151
defer m.lock.RUnlock()
155152

156153
s := set.New[digest.Digest]()
157-
for desc := range m.nodes {
158-
s.Add(desc.Digest)
154+
for digest := range m.nodes {
155+
s.Add(digest)
159156
}
160157
return s
161158
}
@@ -170,22 +167,20 @@ func (m *Memory) index(ctx context.Context, fetcher content.Fetcher, node ocispe
170167
defer m.lock.Unlock()
171168

172169
// index the node
173-
nodeKey := descriptor.FromOCI(node)
174-
m.nodes[nodeKey] = node
170+
m.nodes[node.Digest] = node
175171

176172
// for each successor, put it into the node's successors list, and
177173
// put node into the succeesor's predecessors list
178-
successorSet := set.New[descriptor.Descriptor]()
179-
m.successors[nodeKey] = successorSet
174+
successorSet := set.New[digest.Digest]()
175+
m.successors[node.Digest] = successorSet
180176
for _, successor := range successors {
181-
successorKey := descriptor.FromOCI(successor)
182-
successorSet.Add(successorKey)
183-
predecessorSet, exists := m.predecessors[successorKey]
177+
successorSet.Add(successor.Digest)
178+
predecessorSet, exists := m.predecessors[successor.Digest]
184179
if !exists {
185-
predecessorSet = set.New[descriptor.Descriptor]()
186-
m.predecessors[successorKey] = predecessorSet
180+
predecessorSet = set.New[digest.Digest]()
181+
m.predecessors[successor.Digest] = predecessorSet
187182
}
188-
predecessorSet.Add(nodeKey)
183+
predecessorSet.Add(node.Digest)
189184
}
190185
return successors, nil
191186
}
@@ -195,7 +190,6 @@ func (m *Memory) Exists(node ocispec.Descriptor) bool {
195190
m.lock.RLock()
196191
defer m.lock.RUnlock()
197192

198-
nodeKey := descriptor.FromOCI(node)
199-
_, exists := m.nodes[nodeKey]
193+
_, exists := m.nodes[node.Digest]
200194
return exists
201195
}

0 commit comments

Comments
 (0)