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

     1  package ds
     2  
     3  import (
     4  	"github.com/15mga/kiwi/util"
     5  )
     6  
     7  func newArrayBase[T comparable](defCap int) arrayBase[T] {
     8  	return arrayBase[T]{
     9  		items:  make([]T, defCap),
    10  		defCap: defCap,
    11  		defVal: util.Default[T](),
    12  	}
    13  }
    14  
    15  type arrayBase[T comparable] struct {
    16  	items  []T
    17  	count  int
    18  	defCap int
    19  	defVal T
    20  }
    21  
    22  func (a *arrayBase[T]) Count() int {
    23  	return a.count
    24  }
    25  
    26  func (a *arrayBase[T]) Add(item T) {
    27  	a.testGrow(1)
    28  	a.items[a.count] = item
    29  	a.count++
    30  }
    31  
    32  func (a *arrayBase[T]) AddRange(items ...T) {
    33  	l := len(items)
    34  	if l == 0 {
    35  		return
    36  	}
    37  	a.testGrow(l)
    38  	for i, item := range items {
    39  		a.items[a.count+i] = item
    40  	}
    41  	a.count += l
    42  }
    43  
    44  //func (a *arrayBase[T]) Del(v T) (exist bool) {
    45  //	panic("not implement")
    46  //}
    47  
    48  func (a *arrayBase[T]) testGrow(n int) {
    49  	c, ok := util.NextCap(a.count+n, len(a.items), 1024)
    50  	if !ok {
    51  		return
    52  	}
    53  	ns := make([]T, c)
    54  	copy(ns, a.items)
    55  	a.items = ns
    56  }
    57  
    58  func (a *arrayBase[T]) Clean() {
    59  	a.count = 0
    60  }
    61  
    62  func (a *arrayBase[T]) Reset() {
    63  	if a.count == 0 {
    64  		return
    65  	}
    66  	if len(a.items) > (a.defCap << 2) {
    67  		a.items = make([]T, a.defCap)
    68  	} else {
    69  		for i := 0; i < a.count; i++ {
    70  			a.items[i] = a.defVal
    71  		}
    72  	}
    73  	a.count = 0
    74  }
    75  
    76  func (a *arrayBase[T]) Values() []T {
    77  	return a.items[:a.count]
    78  }
    79  
    80  func (a *arrayBase[T]) HasItem(item T) bool {
    81  	for i := 0; i < a.count; i++ {
    82  		if a.items[i] == item {
    83  			return true
    84  		}
    85  	}
    86  	return false
    87  }
    88  
    89  func NewArray[T comparable](defCap int) *Array[T] {
    90  	return &Array[T]{
    91  		arrayBase: newArrayBase[T](defCap),
    92  	}
    93  }
    94  
    95  // Array 无序数组
    96  type Array[T comparable] struct {
    97  	arrayBase[T]
    98  }
    99  
   100  func (a *Array[T]) Del(v T) (exist bool) {
   101  	var idx int
   102  	for i, item := range a.items {
   103  		if item == v {
   104  			exist = true
   105  			idx = i
   106  			break
   107  		}
   108  	}
   109  	if !exist {
   110  		return
   111  	}
   112  	c := a.count - 1
   113  	if idx == c || c == 0 {
   114  		a.items[idx] = a.defVal
   115  		a.count = c
   116  	} else {
   117  		tail := a.items[c]
   118  		a.items[idx] = tail
   119  		a.items[c] = a.defVal
   120  		a.count = c
   121  		a.testShrink()
   122  	}
   123  	return
   124  }
   125  
   126  func (a *Array[T]) testShrink() {
   127  	c := len(a.items)
   128  	if c == a.defCap {
   129  		return
   130  	}
   131  	var l int
   132  	if c < 1024 {
   133  		l = c >> 1
   134  	} else {
   135  		l = c / 2
   136  	}
   137  	if a.count > l {
   138  		return
   139  	}
   140  	ns := make([]T, l)
   141  	copy(ns, a.items)
   142  	a.items = ns
   143  }
   144  
   145  func NewList[T comparable](defCap int) *List[T] {
   146  	return &List[T]{
   147  		arrayBase: newArrayBase[T](defCap),
   148  	}
   149  }
   150  
   151  // List 有序数组
   152  type List[T comparable] struct {
   153  	arrayBase[T]
   154  }
   155  
   156  func (l *List[T]) Del(v T) (exist bool) {
   157  	var idx int
   158  	for i, item := range l.items {
   159  		if item == v {
   160  			exist = true
   161  			idx = i
   162  			break
   163  		}
   164  	}
   165  	if !exist {
   166  		return
   167  	}
   168  	c := l.count - 1
   169  	if idx == c || c == 0 {
   170  		l.items[idx] = l.defVal
   171  	} else {
   172  		if n, ok := l.isNeedShrink(); ok {
   173  			ns := make([]T, n)
   174  			copy(ns, l.items[:idx])
   175  			copy(ns[idx:], l.items[idx+1:])
   176  		} else {
   177  			//copy(l.items[:idx], l.items[idx+1:])
   178  			l.items = append(l.items[:idx], l.items[idx+1:]...)
   179  		}
   180  	}
   181  	l.count = c
   182  	return
   183  }
   184  
   185  func (l *List[T]) isNeedShrink() (int, bool) {
   186  	c := len(l.items)
   187  	if c == l.defCap {
   188  		return 0, false
   189  	}
   190  
   191  	var n int
   192  	if c < 1024 {
   193  		n = c >> 1
   194  	} else {
   195  		n = c / 2
   196  	}
   197  	if l.count > n {
   198  		return 0, false
   199  	}
   200  	return n, true
   201  }