github.com/cilium/cilium@v1.16.2/pkg/bgpv1/manager/store/diffstore_fake.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package store 5 6 import ( 7 "golang.org/x/exp/maps" 8 "k8s.io/apimachinery/pkg/runtime" 9 10 "github.com/cilium/cilium/pkg/k8s/resource" 11 "github.com/cilium/cilium/pkg/lock" 12 ) 13 14 var _ DiffStore[*runtime.Unknown] = (*fakeDiffStore[*runtime.Unknown])(nil) 15 16 type fakeDiffStore[T runtime.Object] struct { 17 objMu lock.Mutex 18 objects map[resource.Key]T 19 20 changedMu lock.Mutex 21 changed map[string]updatedKeysMap // updated keys per caller ID 22 } 23 24 func NewFakeDiffStore[T runtime.Object]() *fakeDiffStore[T] { 25 return &fakeDiffStore[T]{ 26 objects: make(map[resource.Key]T), 27 changed: make(map[string]updatedKeysMap), 28 } 29 } 30 31 func InitFakeDiffStore[T runtime.Object](objs []T) *fakeDiffStore[T] { 32 mds := NewFakeDiffStore[T]() 33 for _, obj := range objs { 34 mds.Upsert(obj) 35 } 36 return mds 37 } 38 func (mds *fakeDiffStore[T]) InitDiff(callerID string) { 39 mds.changedMu.Lock() 40 defer mds.changedMu.Unlock() 41 42 mds.changed[callerID] = make(map[resource.Key]bool) 43 } 44 45 func (mds *fakeDiffStore[T]) Diff(callerID string) (upserted []T, deleted []resource.Key, err error) { 46 mds.changedMu.Lock() 47 defer mds.changedMu.Unlock() 48 49 changed, ok := mds.changed[callerID] 50 if !ok { 51 return nil, nil, ErrDiffUninitialized 52 } 53 54 for key := range changed { 55 obj, exists, err := mds.GetByKey(key) 56 if err != nil { 57 return nil, nil, err 58 } 59 if exists { 60 upserted = append(upserted, obj) 61 } else { 62 deleted = append(deleted, key) 63 } 64 } 65 66 // Reset the changed map 67 mds.changed[callerID] = make(map[resource.Key]bool) 68 69 return upserted, deleted, nil 70 } 71 72 func (mds *fakeDiffStore[T]) CleanupDiff(callerID string) { 73 mds.changedMu.Lock() 74 defer mds.changedMu.Unlock() 75 76 delete(mds.changed, callerID) 77 } 78 79 // List returns all items currently in the store. 80 func (mds *fakeDiffStore[T]) List() ([]T, error) { 81 mds.objMu.Lock() 82 defer mds.objMu.Unlock() 83 return maps.Values(mds.objects), nil 84 } 85 86 // GetByKey returns the latest version of the object with given key. 87 func (mds *fakeDiffStore[T]) GetByKey(key resource.Key) (item T, exists bool, err error) { 88 mds.objMu.Lock() 89 defer mds.objMu.Unlock() 90 91 item, exists = mds.objects[key] 92 93 return item, exists, nil 94 } 95 96 func (mds *fakeDiffStore[T]) Upsert(obj T) { 97 mds.objMu.Lock() 98 mds.changedMu.Lock() 99 defer mds.objMu.Unlock() 100 defer mds.changedMu.Unlock() 101 102 key := resource.NewKey(obj) 103 mds.objects[key] = obj 104 for _, changed := range mds.changed { 105 changed[key] = true 106 } 107 } 108 109 func (mds *fakeDiffStore[T]) Delete(key resource.Key) { 110 mds.objMu.Lock() 111 mds.changedMu.Lock() 112 defer mds.objMu.Unlock() 113 defer mds.changedMu.Unlock() 114 115 delete(mds.objects, key) 116 for _, changed := range mds.changed { 117 changed[key] = true 118 } 119 }