diff --git a/README.md b/README.md index deb7f2f..1d56bbc 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ And add more detailed documents. ## Go Doc Clock to view the [generated doc](generated_doc.md). + ## Reference - [C++ STL](https://en.wikipedia.org/wiki/Standard_Template_Library) diff --git a/builtin_set.go b/builtin_set.go index b0f70ec..68d285c 100644 --- a/builtin_set.go +++ b/builtin_set.go @@ -14,47 +14,56 @@ func MakeBuiltinSetOf[K comparable](ks ...K) BuiltinSet[K] { return s } +// IsEmpty implements the Container interface. func (s *BuiltinSet[K]) IsEmpty() bool { return len(*s) == 0 } +// Len implements the Container interface. func (s *BuiltinSet[K]) Len() int { return len(*s) } +// Clear implements the Container interface. func (s *BuiltinSet[K]) Clear() { for k := range *s { delete(*s, k) } } +// Has implements the Set interface. func (s *BuiltinSet[K]) Has(k K) bool { _, ok := (*s)[k] return ok } +// Insert implements the Set interface. func (s *BuiltinSet[K]) Insert(k K) { (*s)[k] = true } +// InsertN implements the Set interface. func (s *BuiltinSet[K]) InsertN(ks ...K) { for _, key := range ks { (*s)[key] = true } } +// Remove implements the Set interface. func (s *BuiltinSet[K]) Remove(k K) bool { _, ok := (*s)[k] delete(*s, k) return ok } +// RemoveN implements the Set interface. func (s *BuiltinSet[K]) RemoveN(ks ...K) { for _, k := range ks { delete(*s, k) } } +// Keys return a copy of all keys as a slice. func (s *BuiltinSet[K]) Keys() []K { keys := make([]K, 0, len(*s)) for k := range *s { @@ -63,12 +72,14 @@ func (s *BuiltinSet[K]) Keys() []K { return keys } +// ForEach implements the Set interface. func (s *BuiltinSet[K]) ForEach(cb func(k K)) { for k := range *s { cb(k) } } +// ForEachIf implements the Container interface. func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool) { for k := range *s { if !cb(k) { @@ -77,6 +88,7 @@ func (s *BuiltinSet[K]) ForEachIf(cb func(k K) bool) { } } +// String implements the fmt.Stringer interface func (s BuiltinSet[K]) String() string { return fmt.Sprintf("BuiltinSet[%s]%v", nameOfType[K](), s.Keys()) } diff --git a/dlist.go b/dlist.go index a65478e..e624c8b 100644 --- a/dlist.go +++ b/dlist.go @@ -74,6 +74,7 @@ func (l *DList[T]) Iterate() Iterator[T] { return &dlistIterator[T]{l, l.head.next} } +// PushFront pushes an element at the front of the list. func (l *DList[T]) PushFront(val T) { n := dListNode[T]{&l.head, l.head.next, val} l.head.next.prev = &n @@ -81,6 +82,7 @@ func (l *DList[T]) PushFront(val T) { l.length++ } +// PushBack pushes an element at the back of the list. func (l *DList[T]) PushBack(val T) { n := dListNode[T]{l.head.prev, &l.head, val} l.head.prev.next = &n @@ -88,6 +90,7 @@ func (l *DList[T]) PushBack(val T) { l.length++ } +// PopFront popups a element from the front of the list. func (l *DList[T]) PopFront() (T, bool) { var val T if l.length == 0 { @@ -100,6 +103,7 @@ func (l *DList[T]) PopFront() (T, bool) { return val, true } +// PopBack popups a element from the back of the list. func (l *DList[T]) PopBack() (T, bool) { var val T if l.length == 0 { @@ -119,7 +123,7 @@ func (l *DList[T]) ForEach(cb func(val T)) { } } -// ForEach iterate the list, apply each element to the cb callback function, stop if cb returns false. +// ForEachIf iterate the list, apply each element to the cb callback function, stop if cb returns false. func (l *DList[T]) ForEachIf(cb func(val T) bool) { for n := l.head.next; n != &l.head; n = n.next { if !cb(n.value) { diff --git a/queue.go b/queue.go index a6b3d10..3219367 100644 --- a/queue.go +++ b/queue.go @@ -16,34 +16,42 @@ func NewQueue[T any]() *Queue[T] { return &q } +// Len implements the Container interface. func (q *Queue[T]) Len() int { return q.list.Len() } +// IsEmpty implements the Container interface. func (q *Queue[T]) IsEmpty() bool { return q.list.IsEmpty() } +// Clear implements the Container interface. func (q *Queue[T]) Clear() { q.list.Clear() } +// Len implements the fmt.Stringer interface. func (q *Queue[T]) String() string { return fmt.Sprintf("Queue[%v]", nameOfType[T]()) } +// PushFront pushed an element to the front of the queue. func (q *Queue[T]) PushFront(val T) { q.list.PushFront(val) } +// PushBack pushed an element to the back of the queue. func (q *Queue[T]) PushBack(val T) { q.list.PushBack(val) } +// PopFront popups an element from the front of the queue. func (q *Queue[T]) PopFront() (T, bool) { return q.list.PopFront() } +// PopBack popups an element from the back of the queue. func (q *Queue[T]) PopBack() (T, bool) { return q.list.PopBack() } diff --git a/skiplist.go b/skiplist.go index d22b6e3..eb85c1d 100644 --- a/skiplist.go +++ b/skiplist.go @@ -26,27 +26,20 @@ const ( // // See https://en.wikipedia.org/wiki/Skip_list for more details. type SkipList[K any, V any] struct { - level int // Current level, may increase dynamically during insertion - len int // Total elements numner in the skiplist. - head skipListNode[K, V] + level int // Current level, may increase dynamically during insertion + len int // Total elements numner in the skiplist. + head skipListNode[K, V] // head.next[level] is the head of each level. // This cache is used to save the previous nodes when modifying the skip list to avoid // allocating memory each time it is called. - prevsCache []*skipListNode[K, V] // Cache to avoid memory allocation. + prevsCache []*skipListNode[K, V] rander *rand.Rand impl skipListImpl[K, V] } // NewSkipList creates a new SkipList for Ordered key type. func NewSkipList[K Ordered, V any]() *SkipList[K, V] { - sl := skipListOrdered[K, V]{ - SkipList: SkipList[K, V]{ - level: 1, - // #nosec G404 -- This is not a security condition - rander: rand.New(rand.NewSource(time.Now().Unix())), - prevsCache: make([]*skipListNode[K, V], skipListMaxLevel), - }, - } - sl.head.next = make([]*skipListNode[K, V], skipListMaxLevel) + sl := skipListOrdered[K, V]{} + sl.init() sl.impl = (skipListImpl[K, V])(&sl) return &sl.SkipList } @@ -69,14 +62,17 @@ func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V] { return &sl.SkipList } +// IsEmpty implements the Container interface. func (sl *SkipList[K, V]) IsEmpty() bool { return sl.len == 0 } +// Len implements the Container interface. func (sl *SkipList[K, V]) Len() int { return sl.len } +// Clear implements the Container interface. func (sl *SkipList[K, V]) Clear() { for i := range sl.head.next { sl.head.next[i] = nil @@ -85,6 +81,7 @@ func (sl *SkipList[K, V]) Clear() { sl.len = 0 } +// Iterate return an iterator to the skiplist. func (sl *SkipList[K, V]) Iterate() MapIterator[K, V] { return &skipListIterator[K, V]{sl.head.next[0], nil} } @@ -128,14 +125,21 @@ func (sl *SkipList[K, V]) Find(key K) *V { return nil } +// Has implement the Map interface. func (sl *SkipList[K, V]) Has(key K) bool { return sl.impl.findNode(key) != nil } +// LowerBound returns an iterator to the first element in the skiplist that +// does not satisfy element < value (i.e. greater or equal to), +// or a end itetator if no such element is found. func (sl *SkipList[K, V]) LowerBound(key K) MapIterator[K, V] { return &skipListIterator[K, V]{sl.impl.lowerBound(key), nil} } +// UpperBound returns an iterator to the first element in the skiplist that +// does not satisfy value < element (i.e. strictly greater), +// or a end itetator if no such element is found. func (sl *SkipList[K, V]) UpperBound(key K) MapIterator[K, V] { return &skipListIterator[K, V]{sl.impl.upperBound(key), nil} } @@ -162,18 +166,21 @@ func (sl *SkipList[K, V]) Remove(key K) bool { return true } +// ForEach implements the Map interface. func (sl *SkipList[K, V]) ForEach(op func(K, V)) { for e := sl.head.next[0]; e != nil; e = e.next[0] { op(e.key, e.value) } } +// ForEachMutable implements the Map interface. func (sl *SkipList[K, V]) ForEachMutable(op func(K, *V)) { for e := sl.head.next[0]; e != nil; e = e.next[0] { op(e.key, &e.value) } } +// ForEachIf implements the Map interface. func (sl *SkipList[K, V]) ForEachIf(op func(K, V) bool) { for e := sl.head.next[0]; e != nil; e = e.next[0] { if !op(e.key, e.value) { @@ -182,6 +189,7 @@ func (sl *SkipList[K, V]) ForEachIf(op func(K, V) bool) { } } +// ForEachMutableIf implements the Map interface. func (sl *SkipList[K, V]) ForEachMutableIf(op func(K, *V) bool) { for e := sl.head.next[0]; e != nil; e = e.next[0] { if !op(e.key, &e.value) { diff --git a/skiplist_test.go b/skiplist_test.go index 93ad0ee..489d890 100644 --- a/skiplist_test.go +++ b/skiplist_test.go @@ -105,7 +105,7 @@ func TestNewSkipList_Iterate(t *testing.T) { } } -func testNewSkipList_Iterater(t *testing.T, sl *SkipList[int, int]) { +func testNewSkipListIterater(t *testing.T, sl *SkipList[int, int]) { t.Run("LowerBound", func(t *testing.T) { expectEq(t, sl.LowerBound(1).Key(), 1) expectEq(t, sl.LowerBound(3).Key(), 4) @@ -131,7 +131,7 @@ func testNewSkipList_Iterater(t *testing.T, sl *SkipList[int, int]) { func TestNewSkipList_Iterater(t *testing.T) { sl := NewSkipListFromMap(map[int]int{1: 1, 2: 2, 4: 4}) - testNewSkipList_Iterater(t, sl) + testNewSkipListIterater(t, sl) } func TestNewSkipList_Func_Iterater(t *testing.T) { @@ -140,7 +140,7 @@ func TestNewSkipList_Func_Iterater(t *testing.T) { for k, v := range m { sl.Insert(k, v) } - testNewSkipList_Iterater(t, sl) + testNewSkipListIterater(t, sl) } func TestSkipList_Insert(t *testing.T) { sl := NewSkipList[int, int]() diff --git a/stack.go b/stack.go index 0f369fb..05150ae 100644 --- a/stack.go +++ b/stack.go @@ -16,26 +16,32 @@ func NewStackCap[T any](capicity int) *Stack[T] { return &Stack[T]{make([]T, 0, capicity)} } +// IsEmpty implements the Container interface. func (s *Stack[T]) IsEmpty() bool { return len(s.ele) == 0 } +// Len implements the Container interface. func (s *Stack[T]) Len() int { return len(s.ele) } +// Cap returns the capacity of the stack. func (s *Stack[T]) Cap() int { return cap(s.ele) } +// Clear implements the Container interface. func (s *Stack[T]) Clear() { s.ele = s.ele[0:0] } +// Push pushes the element to the top of the stack. func (s *Stack[T]) Push(t T) { s.ele = append(s.ele, t) } +// Pop try popup an element from the top of the stack. func (s *Stack[T]) Pop() (val T, ok bool) { var t T if len(s.ele) == 0 { @@ -46,6 +52,9 @@ func (s *Stack[T]) Pop() (val T, ok bool) { return t, true } +// MustPop popups an element from the top of the stack. +// It must be called whtn IsEmpty() returned false, +// otherwise it will panic. func (s *Stack[T]) MustPop() T { t := s.ele[len(s.ele)-1] s.ele = s.ele[:len(s.ele)-1] diff --git a/vector.go b/vector.go index 0c17217..b9d1ecf 100644 --- a/vector.go +++ b/vector.go @@ -19,14 +19,17 @@ func MakeVectorOf[T any](v ...T) Vector[T] { return (Vector[T])(v) } +// IsEmpty implements the Container interface. func (v *Vector[T]) IsEmpty() bool { return len(*v) == 0 } +// Len implements the Container interface. func (v *Vector[T]) Len() int { return len(*v) } +// Cap returns the capacity of the vector. func (v *Vector[T]) Cap() int { return cap(*v) } @@ -58,14 +61,19 @@ func (v *Vector[T]) Shrink() { } } +// At returns the element value at the index i. +// You can also use the [] operator, and it's better. func (v *Vector[T]) At(i int) T { return (*v)[i] } +// Set sets the value of the element at the index i. +// You can also use the [] operator, and it's better. func (v *Vector[T]) Set(i int, x T) { (*v)[i] = x } +// PushBack pushs an element to the end of the vector. func (v *Vector[T]) PushBack(x T) { *v = append(*v, x) } @@ -104,12 +112,12 @@ func (v *Vector[T]) Remove(i int) { v.RemoveRange(i, i+1) } -// Remove removes the elements in the range[i, j) from the vector. +// RemoveRange removes the elements in the range[i, j) from the vector. func (v *Vector[T]) RemoveRange(i, j int) { *v = append((*v)[:i], (*v)[j:]...) } -// Remove removes the elements in the range[i, i+len) from the vector. +// RemoveLength removes the elements in the range[i, i+len) from the vector. func (v *Vector[T]) RemoveLength(i int, len int) { v.RemoveRange(i, i+len) }