Skip to content

Commit

Permalink
changed successors to regular maps, updated tests
Browse files Browse the repository at this point in the history
Signed-off-by: Xiaoxuan Wang <wangxiaoxuan119@gmail.com>
  • Loading branch information
wangxiaoxuan273 committed Sep 7, 2023
1 parent 8e946ab commit 49cfe2b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 44 deletions.
30 changes: 14 additions & 16 deletions internal/graph/memoryWithDelete.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ import (

// MemoryWithDelete is a MemoryWithDelete based PredecessorFinder.
type MemoryWithDelete struct {
indexed sync.Map // map[descriptor.Descriptor]any
indexed sync.Map // map[descriptor.Descriptor]any, this variable is only used by IndexAll
predecessors sync.Map // map[descriptor.Descriptor]map[descriptor.Descriptor]ocispec.Descriptor
successors sync.Map // map[descriptor.Descriptor]map[descriptor.Descriptor]ocispec.Descriptor
successors map[descriptor.Descriptor]map[descriptor.Descriptor]ocispec.Descriptor
lock sync.Mutex
}

// NewMemoryWithDelete creates a new MemoryWithDelete PredecessorFinder.
func NewMemoryWithDelete() *MemoryWithDelete {
return &MemoryWithDelete{}
return &MemoryWithDelete{
successors: make(map[descriptor.Descriptor]map[descriptor.Descriptor]ocispec.Descriptor),
}
}

// Index indexes predecessors for each direct successor of the given node.
Expand Down Expand Up @@ -124,14 +126,11 @@ func (m *MemoryWithDelete) Remove(ctx context.Context, node ocispec.Descriptor)
defer m.lock.Unlock()
nodeKey := descriptor.FromOCI(node)
// remove the node from its successors' predecessor list
value, _ := m.successors.Load(nodeKey)
successors := value.(*sync.Map)
successors.Range(func(key, _ interface{}) bool {
value, _ = m.predecessors.Load(key)
for successorKey, _ := range m.successors[nodeKey] {
value, _ := m.predecessors.Load(successorKey)
predecessors := value.(*sync.Map)
predecessors.Delete(nodeKey)
return true
})
}
m.removeEntriesFromMaps(ctx, node)
return nil
}
Expand All @@ -154,21 +153,20 @@ func (m *MemoryWithDelete) index(ctx context.Context, node ocispec.Descriptor, s
predecessorsMap := pred.(*sync.Map)
predecessorsMap.Store(predecessorKey, node)
// store in m.successors, MemoryWithDelete.successors[predecessorKey].Store(successor)
succ, _ := m.successors.Load(predecessorKey)
successorsMap := succ.(*sync.Map)
successorsMap.Store(successorKey, successor)
m.successors[predecessorKey][successorKey] = successor
}
}

func (m *MemoryWithDelete) createEntriesInMaps(ctx context.Context, node ocispec.Descriptor) {
key := descriptor.FromOCI(node)
m.predecessors.LoadOrStore(key, &sync.Map{})
m.successors.LoadOrStore(key, &sync.Map{})
if _, hasEntry := m.successors[key]; !hasEntry {
m.successors[key] = make(map[descriptor.Descriptor]ocispec.Descriptor)
}
}

func (m *MemoryWithDelete) removeEntriesFromMaps(ctx context.Context, node ocispec.Descriptor) {
key := descriptor.FromOCI(node)
m.predecessors.Delete(key)
m.successors.Delete(key)
m.indexed.Delete(key)
delete(m.successors, key)
m.indexed.Delete(key) // pending
}
49 changes: 21 additions & 28 deletions internal/graph/memoryWithDelete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,21 @@ func TestMemoryWithDelete_indexAndDelete(t *testing.T) {
// test 1: index "A -> B"
testMemoryWithDelete.index(ctx, A, []ocispec.Descriptor{B})

// check the MemoryWithDelete: A exists in testMemoryWithDelete.predecessors and successors
// check the memory: A exists in predecessors and successors
// B ONLY exists in predecessors
_, exists := testMemoryWithDelete.predecessors.Load(AKey)
if !exists {
t.Errorf("could not find the entry of %v in predecessors", A)
}
_, exists = testMemoryWithDelete.successors.Load(AKey)
_, exists = testMemoryWithDelete.successors[AKey]
if !exists {
t.Errorf("could not find the entry of %v in successors", A)
}
_, exists = testMemoryWithDelete.predecessors.Load(BKey)
if !exists {
t.Errorf("could not find the entry of %v in predecessors", B)
}
_, exists = testMemoryWithDelete.successors.Load(BKey)
_, exists = testMemoryWithDelete.successors[BKey]
if exists {
t.Errorf("%v should not exist in successors", B)
}
Expand All @@ -86,39 +86,37 @@ func TestMemoryWithDelete_indexAndDelete(t *testing.T) {
if !exists {
t.Errorf("could not find %v in predecessors of %v", A, B)
}
value, _ = testMemoryWithDelete.successors.Load(AKey)
ASuccs := value.(*sync.Map)
_, exists = ASuccs.Load(BKey)
_, exists = testMemoryWithDelete.successors[AKey][BKey]
if !exists {
t.Errorf("could not find %v in successors of %v", B, A)
}

// test 2: index "B -> C, B -> D"
testMemoryWithDelete.index(ctx, B, []ocispec.Descriptor{C, D})

// check the MemoryWithDelete: B exists in testMemoryWithDelete.predecessors, successors and indexed,
// check the memory: B exists in predecessors and successors,
// C, D ONLY exists in predecessors
_, exists = testMemoryWithDelete.predecessors.Load(BKey)
if !exists {
t.Errorf("could not find the entry of %v in predecessors", B)
}
_, exists = testMemoryWithDelete.successors.Load(BKey)
_, exists = testMemoryWithDelete.successors[BKey]
if !exists {
t.Errorf("could not find the entry of %v in successors", B)
}
_, exists = testMemoryWithDelete.predecessors.Load(CKey)
if !exists {
t.Errorf("could not find the entry of %v in predecessors", C)
}
_, exists = testMemoryWithDelete.successors.Load(CKey)
_, exists = testMemoryWithDelete.successors[CKey]
if exists {
t.Errorf("%v should not exist in successors", C)
}
_, exists = testMemoryWithDelete.predecessors.Load(DKey)
if !exists {
t.Errorf("could not find the entry of %v in predecessors", D)
}
_, exists = testMemoryWithDelete.successors.Load(DKey)
_, exists = testMemoryWithDelete.successors[DKey]
if exists {
t.Errorf("%v should not exist in successors", D)
}
Expand All @@ -136,13 +134,11 @@ func TestMemoryWithDelete_indexAndDelete(t *testing.T) {
if !exists {
t.Errorf("could not find %v in predecessors of %v", B, D)
}
value, _ = testMemoryWithDelete.successors.Load(BKey)
BSuccs := value.(*sync.Map)
_, exists = BSuccs.Load(CKey)
_, exists = testMemoryWithDelete.successors[BKey][CKey]
if !exists {
t.Errorf("could not find %v in successors of %v", C, B)
}
_, exists = BSuccs.Load(DKey)
_, exists = testMemoryWithDelete.successors[BKey][DKey]
if !exists {
t.Errorf("could not find %v in successors of %v", D, B)
}
Expand All @@ -161,24 +157,22 @@ func TestMemoryWithDelete_indexAndDelete(t *testing.T) {
if !exists {
t.Errorf("could not find %v in predecessors of %v", B, D)
}
value, _ = testMemoryWithDelete.successors.Load(AKey)
ASuccs = value.(*sync.Map)
_, exists = ASuccs.Load(BKey)
_, exists = testMemoryWithDelete.successors[AKey][BKey]
if !exists {
t.Errorf("could not find %v in successors of %v", B, A)
}
_, exists = ASuccs.Load(DKey)
_, exists = testMemoryWithDelete.successors[AKey][DKey]
if !exists {
t.Errorf("could not find %v in successors of %v", D, A)
}

// check the MemoryWithDelete: C and D have not been indexed, so C, D should not
// check the memory: C and D have not been indexed, so C, D should not
// exist in successors
_, exists = testMemoryWithDelete.successors.Load(CKey)
_, exists = testMemoryWithDelete.successors[CKey]
if exists {
t.Errorf("%v should not exist in successors", C)
}
_, exists = testMemoryWithDelete.successors.Load(DKey)
_, exists = testMemoryWithDelete.successors[DKey]
if exists {
t.Errorf("%v should not exist in successors", D)
}
Expand All @@ -189,20 +183,19 @@ func TestMemoryWithDelete_indexAndDelete(t *testing.T) {
t.Errorf("got error when removing %v from index: %v", B, err)
}

// check the MemoryWithDelete: B should NOT exist in predecessors, successors and indexed
// check the memory: B should NOT exist in successors, should still exist
// in predecessors
_, exists = testMemoryWithDelete.predecessors.Load(BKey)
if exists {
t.Errorf("%v should not exist in predecessors", B)
if !exists {
t.Errorf("%v should exist in predecessors", B)
}
_, exists = testMemoryWithDelete.successors.Load(BKey)
_, exists = testMemoryWithDelete.successors[BKey]
if exists {
t.Errorf("%v should not exist in successors", B)
}

// B should STILL exist in successors[A]
value, _ = testMemoryWithDelete.successors.Load(AKey)
ASuccs = value.(*sync.Map)
_, exists = ASuccs.Load(BKey)
_, exists = testMemoryWithDelete.successors[AKey][BKey]
if !exists {
t.Errorf("could not find %v in successors of %v", B, A)
}
Expand Down

0 comments on commit 49cfe2b

Please sign in to comment.