github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/ds/set.go (about)

     1  package ds
     2  
     3  import (
     4  	"github.com/15mga/kiwi/util"
     5  )
     6  
     7  func NewKSet[KT comparable, VT any](defCap int, getKey func(VT) KT) *KSet[KT, VT] {
     8  	if defCap == 0 {
     9  		defCap = 1
    10  	}
    11  	return &KSet[KT, VT]{
    12  		items:    make([]VT, defCap),
    13  		keyToIdx: make(map[KT]int, defCap),
    14  		cap:      defCap,
    15  		defCap:   defCap,
    16  		getKey:   getKey,
    17  		defVal:   util.Default[VT](),
    18  	}
    19  }
    20  
    21  type KSet[KT comparable, VT any] struct {
    22  	items    []VT
    23  	keyToIdx map[KT]int
    24  	count    int
    25  	cap      int
    26  	defCap   int
    27  	getKey   func(VT) KT
    28  	defVal   VT
    29  }
    30  
    31  func (s *KSet[KT, VT]) Count() int {
    32  	return s.count
    33  }
    34  
    35  func (s *KSet[KT, VT]) Cap() int {
    36  	return s.cap
    37  }
    38  
    39  func (s *KSet[KT, VT]) Add(item VT) *util.Err {
    40  	key := s.getKey(item)
    41  	_, ok := s.keyToIdx[key]
    42  	if ok {
    43  		return util.NewErr(util.EcExist, util.M{
    44  			"key": key,
    45  		})
    46  	}
    47  	s.add(key, item)
    48  	return nil
    49  }
    50  
    51  func (s *KSet[KT, VT]) AddNX(item VT) bool {
    52  	key := s.getKey(item)
    53  	_, ok := s.keyToIdx[key]
    54  	if ok {
    55  		return false
    56  	}
    57  	s.add(key, item)
    58  	return true
    59  }
    60  
    61  func (s *KSet[KT, VT]) AddNX2(key KT, new func() VT) bool {
    62  	_, ok := s.keyToIdx[key]
    63  	if ok {
    64  		return false
    65  	}
    66  	v := new()
    67  	s.add(key, v)
    68  	return true
    69  }
    70  
    71  func (s *KSet[KT, VT]) AddRange(items []VT) {
    72  	l := len(items)
    73  	s.testGrow(l)
    74  	for i, item := range items {
    75  		s.items[s.count+i] = item
    76  	}
    77  	s.count += l
    78  }
    79  
    80  func (s *KSet[KT, VT]) add(key KT, item VT) {
    81  	s.testGrow(1)
    82  	s.items[s.count] = item
    83  	s.keyToIdx[key] = s.count
    84  	s.count++
    85  }
    86  
    87  func (s *KSet[KT, VT]) testGrow(grow int) {
    88  	c, ok := util.NextCap(s.count+grow, s.cap, 1024)
    89  	if !ok {
    90  		return
    91  	}
    92  	s.cap = c
    93  	ns := make([]VT, s.cap)
    94  	copy(ns, s.items)
    95  	s.items = ns
    96  }
    97  
    98  func (s *KSet[KT, VT]) testShrink() {
    99  	// 缩容
   100  	if s.cap == s.defCap {
   101  		return
   102  	}
   103  	var h int
   104  	if s.cap < 1024 {
   105  		h = s.cap >> 1
   106  	} else {
   107  		h = s.cap / 2
   108  	}
   109  	if s.count > h {
   110  		return
   111  	}
   112  	ns := make([]VT, h)
   113  	copy(ns, s.items[:s.count])
   114  	s.items = ns
   115  	s.cap = h
   116  	nm := make(map[KT]int, s.count)
   117  	for k, v := range s.keyToIdx {
   118  		nm[k] = v
   119  	}
   120  	s.keyToIdx = nm
   121  }
   122  
   123  func (s *KSet[KT, VT]) Set(item VT) (old VT) {
   124  	key := s.getKey(item)
   125  	idx, ok := s.keyToIdx[key]
   126  	if ok {
   127  		old = s.items[idx]
   128  		s.items[idx] = item
   129  		return
   130  	}
   131  	s.add(key, item)
   132  	return
   133  }
   134  
   135  func (s *KSet[KT, VT]) Del(k KT) (val VT, exist bool) {
   136  	idx, ok := s.keyToIdx[k]
   137  	if !ok {
   138  		return
   139  	}
   140  	val = s.items[idx]
   141  	exist = true
   142  	delete(s.keyToIdx, k)
   143  	c := s.count - 1
   144  	if idx == c || c == 0 {
   145  		s.items[idx] = s.defVal
   146  	} else {
   147  		tail := s.items[c]
   148  		s.items[idx] = tail
   149  		s.items[c] = s.defVal
   150  		s.keyToIdx[s.getKey(tail)] = idx
   151  	}
   152  	s.count = c
   153  	s.testShrink()
   154  	return
   155  }
   156  
   157  func (s *KSet[KT, VT]) Reset() {
   158  	for i := 0; i < s.count; i++ {
   159  		s.items[i] = s.defVal
   160  	}
   161  	s.count = 0
   162  	s.keyToIdx = make(map[KT]int, s.defCap)
   163  }
   164  
   165  func (s *KSet[KT, VT]) ReplaceOrNew(oldKey KT, newItem VT) bool {
   166  	idx, ok := s.keyToIdx[oldKey]
   167  	if !ok {
   168  		_ = s.Add(newItem)
   169  		return false
   170  	}
   171  	delete(s.keyToIdx, oldKey)
   172  	s.keyToIdx[s.getKey(newItem)] = idx
   173  	s.items[idx] = newItem
   174  	return true
   175  }
   176  
   177  func (s *KSet[KT, VT]) Get(key KT) (VT, bool) {
   178  	idx, ok := s.keyToIdx[key]
   179  	if !ok {
   180  		return s.defVal, false
   181  	}
   182  	item := s.items[idx]
   183  	return item, true
   184  }
   185  
   186  func (s *KSet[KT, VT]) GetOrNew(key KT, new func() VT) (VT, bool) {
   187  	idx, ok := s.keyToIdx[key]
   188  	if ok {
   189  		return s.items[idx], true
   190  	}
   191  	n := new()
   192  	s.add(key, n)
   193  	return n, false
   194  }
   195  
   196  func (s *KSet[KT, VT]) GetWithIdx(idx int) (VT, bool) {
   197  	if idx >= s.count || idx < 0 {
   198  		return s.defVal, false
   199  	}
   200  	item := s.items[idx]
   201  	return item, true
   202  }
   203  
   204  func (s *KSet[KT, VT]) Has(key KT) bool {
   205  	_, ok := s.keyToIdx[key]
   206  	return ok
   207  }
   208  
   209  func (s *KSet[KT, VT]) Iter(fn func(VT)) {
   210  	for i := 0; i < s.count; i++ {
   211  		fn(s.items[i])
   212  	}
   213  }
   214  
   215  func (s *KSet[KT, VT]) IterKeys(fn func(KT)) {
   216  	for k := range s.keyToIdx {
   217  		fn(k)
   218  	}
   219  }
   220  
   221  func (s *KSet[KT, VT]) Any(fn func(VT) bool) bool {
   222  	for i := 0; i < s.count; i++ {
   223  		item := s.items[i]
   224  		if fn(item) {
   225  			return true
   226  		}
   227  	}
   228  	return false
   229  }
   230  
   231  func (s *KSet[KT, VT]) Values() []VT {
   232  	return s.items[:s.count]
   233  }
   234  
   235  func (s *KSet[KT, VT]) CopyValues(values *[]VT) {
   236  	for _, v := range s.items[:s.count] {
   237  		*values = append(*values, v)
   238  	}
   239  }
   240  
   241  func (s *KSet[KT, VT]) CopyKeys(keys *[]KT) {
   242  	for k := range s.keyToIdx {
   243  		*keys = append(*keys, k)
   244  	}
   245  }
   246  
   247  func (s *KSet[KT, VT]) TestDel(test func(KT, VT) (del bool, brk bool)) {
   248  	for i := s.count; i > 0; {
   249  		i--
   250  		item := s.items[i]
   251  		key := s.getKey(item)
   252  		if ok, brk := test(key, item); ok {
   253  			s.Del(key)
   254  			if !brk {
   255  				break
   256  			}
   257  		}
   258  	}
   259  }
   260  
   261  func NewSet[KT comparable, VT any](defCap int) *KSet[KT, *SetItem[KT, VT]] {
   262  	return NewKSet[KT, *SetItem[KT, VT]](defCap, func(k *SetItem[KT, VT]) KT {
   263  		return k.key
   264  	})
   265  }
   266  
   267  func NewSetItem[KT comparable, VT any](defCap int, key KT, getKey func(VT) KT) *SetItem[KT, VT] {
   268  	return &SetItem[KT, VT]{
   269  		key:  key,
   270  		KSet: NewKSet[KT, VT](defCap, getKey),
   271  	}
   272  }
   273  
   274  type SetItem[KT comparable, VT any] struct {
   275  	key KT
   276  	*KSet[KT, VT]
   277  }
   278  
   279  func (s *SetItem[KT, VT]) ResetKey(key KT) {
   280  	s.key = key
   281  }
   282  
   283  func NewSet2Item[KT1, KT2 comparable, VT any](key KT1, defCap int, getKey func(VT) KT2) *Set2Item[KT1, KT2, VT] {
   284  	return &Set2Item[KT1, KT2, VT]{
   285  		key:  key,
   286  		KSet: NewKSet[KT2, VT](defCap, getKey),
   287  	}
   288  }
   289  
   290  type Set2Item[KT1, KT2 comparable, VT any] struct {
   291  	*KSet[KT2, VT]
   292  	key KT1
   293  }
   294  
   295  func (s *Set2Item[KT1, KT2, VT]) Key() KT1 {
   296  	return s.key
   297  }
   298  
   299  func NewKSet2[KT1, KT2 comparable, VT any](defCap int, getKey func(VT) KT2) *KSet2[KT1, KT2, VT] {
   300  	return &KSet2[KT1, KT2, VT]{
   301  		defCap: defCap,
   302  		getKey: getKey,
   303  		KSet: NewKSet[KT1, *Set2Item[KT1, KT2, VT]](defCap, func(s *Set2Item[KT1, KT2, VT]) KT1 {
   304  			return s.key
   305  		}),
   306  	}
   307  }
   308  
   309  type KSet2[KT1, KT2 comparable, VT any] struct {
   310  	*KSet[KT1, *Set2Item[KT1, KT2, VT]]
   311  	getKey func(VT) KT2
   312  	defCap int
   313  }
   314  
   315  func (s *KSet2[KT1, KT2, VT]) ReplaceKey(old, new KT1) bool {
   316  	idx, ok := s.keyToIdx[old]
   317  	if !ok {
   318  		return false
   319  	}
   320  	s.keyToIdx[new] = idx
   321  	s.items[idx].key = new
   322  	return true
   323  }