github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/tuple/onrset.go (about)

     1  package tuple
     2  
     3  import (
     4  	"maps"
     5  
     6  	expmaps "golang.org/x/exp/maps"
     7  
     8  	core "github.com/authzed/spicedb/pkg/proto/core/v1"
     9  )
    10  
    11  // ONRSet is a set of ObjectAndRelation's.
    12  type ONRSet struct {
    13  	onrs map[string]*core.ObjectAndRelation
    14  }
    15  
    16  // NewONRSet creates a new set.
    17  func NewONRSet(onrs ...*core.ObjectAndRelation) *ONRSet {
    18  	created := &ONRSet{
    19  		onrs: map[string]*core.ObjectAndRelation{},
    20  	}
    21  	created.Update(onrs)
    22  	return created
    23  }
    24  
    25  // Length returns the size of the set.
    26  func (ons *ONRSet) Length() uint64 {
    27  	return uint64(len(ons.onrs))
    28  }
    29  
    30  // IsEmpty returns whether the set is empty.
    31  func (ons *ONRSet) IsEmpty() bool {
    32  	return len(ons.onrs) == 0
    33  }
    34  
    35  // Has returns true if the set contains the given ONR.
    36  func (ons *ONRSet) Has(onr *core.ObjectAndRelation) bool {
    37  	_, ok := ons.onrs[StringONR(onr)]
    38  	return ok
    39  }
    40  
    41  // Add adds the given ONR to the set. Returns true if the object was not in the set before this
    42  // call and false otherwise.
    43  func (ons *ONRSet) Add(onr *core.ObjectAndRelation) bool {
    44  	if _, ok := ons.onrs[StringONR(onr)]; ok {
    45  		return false
    46  	}
    47  
    48  	ons.onrs[StringONR(onr)] = onr
    49  	return true
    50  }
    51  
    52  // Update updates the set by adding the given ONRs to it.
    53  func (ons *ONRSet) Update(onrs []*core.ObjectAndRelation) {
    54  	for _, onr := range onrs {
    55  		ons.Add(onr)
    56  	}
    57  }
    58  
    59  // UpdateFrom updates the set by adding the ONRs found in the other set to it.
    60  func (ons *ONRSet) UpdateFrom(otherSet *ONRSet) {
    61  	for _, onr := range otherSet.onrs {
    62  		ons.Add(onr)
    63  	}
    64  }
    65  
    66  // Intersect returns an intersection between this ONR set and the other set provided.
    67  func (ons *ONRSet) Intersect(otherSet *ONRSet) *ONRSet {
    68  	updated := NewONRSet()
    69  	for _, onr := range ons.onrs {
    70  		if otherSet.Has(onr) {
    71  			updated.Add(onr)
    72  		}
    73  	}
    74  	return updated
    75  }
    76  
    77  // Subtract returns a subtraction from this ONR set of the other set provided.
    78  func (ons *ONRSet) Subtract(otherSet *ONRSet) *ONRSet {
    79  	updated := NewONRSet()
    80  	for _, onr := range ons.onrs {
    81  		if !otherSet.Has(onr) {
    82  			updated.Add(onr)
    83  		}
    84  	}
    85  	return updated
    86  }
    87  
    88  // With returns a copy of this ONR set with the given element added.
    89  func (ons *ONRSet) With(onr *core.ObjectAndRelation) *ONRSet {
    90  	updated := &ONRSet{
    91  		onrs: maps.Clone(ons.onrs),
    92  	}
    93  	updated.Add(onr)
    94  	return updated
    95  }
    96  
    97  // Union returns a copy of this ONR set with the other set's elements added in.
    98  func (ons *ONRSet) Union(otherSet *ONRSet) *ONRSet {
    99  	updated := &ONRSet{
   100  		onrs: maps.Clone(ons.onrs),
   101  	}
   102  	for _, current := range otherSet.onrs {
   103  		updated.Add(current)
   104  	}
   105  	return updated
   106  }
   107  
   108  // AsSlice returns the ONRs found in the set as a slice.
   109  func (ons *ONRSet) AsSlice() []*core.ObjectAndRelation {
   110  	return expmaps.Values(ons.onrs)
   111  }