github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/keyset/keyset_inclusive.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package keyset
     7  
     8  func Nothing() KeySet {
     9  	return inclusiveKeySet{emptyBasicKeySet}
    10  }
    11  
    12  var _ KeyList = inclusiveKeySet{}
    13  
    14  type inclusiveKeySet struct {
    15  	keys internalKeySet
    16  }
    17  
    18  func (v inclusiveKeySet) EnumKeys(fn func(k Key) bool) bool {
    19  	return v.keys.EnumKeys(fn)
    20  }
    21  
    22  func (v inclusiveKeySet) Count() int {
    23  	return v.keys.Count()
    24  }
    25  
    26  func (v inclusiveKeySet) EnumRawKeys(fn func(k Key, exclusive bool) bool) bool {
    27  	return v.keys.enumRawKeys(false, fn)
    28  }
    29  
    30  func (v inclusiveKeySet) RawKeyCount() int {
    31  	return v.keys.Count()
    32  }
    33  
    34  func (v inclusiveKeySet) IsNothing() bool {
    35  	return v.keys.Count() == 0
    36  }
    37  
    38  func (v inclusiveKeySet) IsEverything() bool {
    39  	return false
    40  }
    41  
    42  func (v inclusiveKeySet) IsOpenSet() bool {
    43  	return false
    44  }
    45  
    46  func (v inclusiveKeySet) Contains(k Key) bool {
    47  	return v.keys.Contains(k)
    48  }
    49  
    50  func (v inclusiveKeySet) ContainsAny(ks KeySet) bool {
    51  	switch {
    52  	case ks.IsOpenSet():
    53  		if v.RawKeyCount() > ks.RawKeyCount() {
    54  			return true
    55  		}
    56  	case v.RawKeyCount() > ks.RawKeyCount():
    57  		return ks.EnumRawKeys(func(k Key, _ bool) bool {
    58  			return v.Contains(k)
    59  		})
    60  	}
    61  
    62  	return v.keys.EnumKeys(ks.Contains)
    63  }
    64  
    65  func (v inclusiveKeySet) SupersetOf(ks KeySet) bool {
    66  	if ks.IsOpenSet() || v.RawKeyCount() < ks.RawKeyCount() {
    67  		return false
    68  	}
    69  
    70  	return !ks.EnumRawKeys(func(k Key, _ bool) bool {
    71  		return !v.Contains(k)
    72  	})
    73  }
    74  
    75  func (v inclusiveKeySet) SubsetOf(ks KeySet) bool {
    76  	if v.RawKeyCount() > ks.RawKeyCount() {
    77  		if ks.IsOpenSet() {
    78  			return !ks.EnumRawKeys(func(k Key, _ bool) bool {
    79  				return v.Contains(k)
    80  			})
    81  		}
    82  		return false
    83  	}
    84  
    85  	return !v.keys.EnumKeys(func(k Key) bool {
    86  		return !ks.Contains(k)
    87  	})
    88  }
    89  
    90  func (v inclusiveKeySet) Equal(ks KeySet) bool {
    91  	if ks.IsOpenSet() || v.RawKeyCount() != ks.RawKeyCount() {
    92  		return false
    93  	}
    94  	return !v.keys.EnumKeys(func(k Key) bool {
    95  		return !ks.Contains(k)
    96  	})
    97  }
    98  
    99  func (v inclusiveKeySet) EqualInverse(ks KeySet) bool {
   100  	if !ks.IsOpenSet() || v.RawKeyCount() != ks.RawKeyCount() {
   101  		return false
   102  	}
   103  	return !v.keys.EnumKeys(ks.Contains)
   104  }
   105  
   106  func (v inclusiveKeySet) Inverse() KeySet {
   107  	return exclusiveKeySet(v)
   108  }
   109  
   110  func (v inclusiveKeySet) Union(ks KeySet) KeySet {
   111  	switch {
   112  	case ks.IsOpenSet():
   113  		return ks.Union(v)
   114  	case v.RawKeyCount() == 0:
   115  		return ks
   116  	case ks.RawKeyCount() == 0:
   117  		return v
   118  	}
   119  	return inclusiveKeySet{keyUnion(v.keys, ks)}
   120  }
   121  
   122  func (v inclusiveKeySet) Intersect(ks KeySet) KeySet {
   123  	switch {
   124  	case v.RawKeyCount() == 0:
   125  		return v
   126  	case ks.IsOpenSet():
   127  		return inclusiveKeySet{keySubtract(v.keys, ks)}
   128  	case ks.RawKeyCount() == 0:
   129  		return ks
   130  	}
   131  	return inclusiveKeySet{keyIntersect(v.keys, ks)}
   132  }
   133  
   134  func (v inclusiveKeySet) Subtract(ks KeySet) KeySet {
   135  	switch {
   136  	case v.RawKeyCount() == 0:
   137  		return v
   138  	case ks.IsOpenSet():
   139  		return inclusiveKeySet{keyIntersect(v.keys, ks)}
   140  	case ks.RawKeyCount() == 0:
   141  		return v
   142  	}
   143  	return inclusiveKeySet{keySubtract(v.keys, ks)}
   144  }
   145  
   146  var _ mutableKeySet = &inclusiveMutable{}
   147  
   148  type inclusiveMutable struct {
   149  	inclusiveKeySet
   150  }
   151  
   152  func (v *inclusiveMutable) retainAll(ks KeySet) mutableKeySet {
   153  	keys := v.keys.(basicKeySet)
   154  
   155  	if keys.isEmpty() {
   156  		return nil
   157  	}
   158  
   159  	switch kn := ks.RawKeyCount(); {
   160  	case kn == 0:
   161  		if !ks.IsOpenSet() {
   162  			v.keys = emptyBasicKeySet
   163  		}
   164  		return nil
   165  	case ks.IsOpenSet() && kn < keys.Count():
   166  		ks.EnumRawKeys(func(k Key, exclusive bool) bool {
   167  			keys.remove(k)
   168  			return keys.isEmpty()
   169  		})
   170  	default:
   171  		for k := range keys {
   172  			if !ks.Contains(k) {
   173  				keys.remove(k)
   174  			}
   175  		}
   176  	}
   177  
   178  	if len(keys) == 0 {
   179  		v.keys = emptyBasicKeySet
   180  	}
   181  	return nil
   182  }
   183  
   184  func (v *inclusiveMutable) removeAll(ks KeySet) mutableKeySet {
   185  	keys := v.keys.(basicKeySet)
   186  
   187  	if keys.isEmpty() {
   188  		return nil
   189  	}
   190  
   191  	if ks.IsOpenSet() && keys.Count() > ks.RawKeyCount() {
   192  		var newKeys basicKeySet
   193  		ks.EnumRawKeys(func(k Key, _ bool) bool {
   194  			if keys.Contains(k) {
   195  				if newKeys == nil {
   196  					// there will be no more than ks.RawKeyCount() ...
   197  					newKeys = newBasicKeySet(0)
   198  				}
   199  				newKeys.add(k)
   200  			}
   201  			return false
   202  		})
   203  		v.keys = newKeys
   204  		return nil
   205  	}
   206  
   207  	for k := range keys {
   208  		if ks.Contains(k) {
   209  			keys.remove(k)
   210  		}
   211  	}
   212  
   213  	if len(keys) == 0 {
   214  		v.keys = emptyBasicKeySet
   215  	}
   216  	return nil
   217  }
   218  
   219  func (v *inclusiveMutable) addAll(ks KeySet) mutableKeySet {
   220  	if ks.IsOpenSet() {
   221  		keys := v.keys.(basicKeySet)
   222  
   223  		// NB! it changes a type of the set to exclusive
   224  		var newKeys basicKeySet
   225  		ks.EnumRawKeys(func(k Key, _ bool) bool {
   226  			if !keys.Contains(k) {
   227  				if newKeys == nil {
   228  					newKeys = newBasicKeySet(ks.RawKeyCount())
   229  				}
   230  				newKeys.add(k)
   231  			}
   232  			return false
   233  		})
   234  		return &exclusiveMutable{exclusiveKeySet{newKeys}}
   235  	}
   236  
   237  	kn := ks.RawKeyCount()
   238  	if kn == 0 {
   239  		return nil
   240  	}
   241  
   242  	keys := v.ensureSet(kn)
   243  	ks.EnumRawKeys(func(k Key, _ bool) bool {
   244  		keys.add(k)
   245  		return false
   246  	})
   247  	return nil
   248  }
   249  
   250  func (v *inclusiveMutable) remove(k Key) {
   251  	keys := v.keys.(basicKeySet)
   252  	keys.remove(k)
   253  }
   254  
   255  func (v *inclusiveMutable) removeKeys(ks []Key) {
   256  	keys := v.keys.(basicKeySet)
   257  	for _, k := range ks {
   258  		keys.remove(k)
   259  	}
   260  }
   261  
   262  func (v *inclusiveMutable) add(k Key) {
   263  	keys := v.ensureSet(0)
   264  	keys.add(k)
   265  }
   266  
   267  func (v *inclusiveMutable) addKeys(ks []Key) {
   268  	if len(ks) == 0 {
   269  		return
   270  	}
   271  	keys := v.ensureSet(len(ks))
   272  	for _, k := range ks {
   273  		keys.add(k)
   274  	}
   275  }
   276  
   277  func (v *inclusiveMutable) copy(n int) basicKeySet {
   278  	return v.keys.copy(n)
   279  }
   280  
   281  func (v *inclusiveMutable) ensureSet(n int) basicKeySet {
   282  	keys := v.keys.(basicKeySet)
   283  	if keys == nil {
   284  		keys = newBasicKeySet(n)
   285  		v.keys = keys
   286  	}
   287  	return keys
   288  }