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  }