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