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