Skip to content

Commit

Permalink
Update docs (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
chen3feng committed Aug 15, 2022
1 parent 41cf3ca commit 7d4beb4
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions builtin_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand All @@ -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())
}
6 changes: 5 additions & 1 deletion dlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,23 @@ 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
l.head.next = &n
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
l.head.prev = &n
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 {
Expand All @@ -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 {
Expand All @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
34 changes: 21 additions & 13 deletions skiplist.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
Expand All @@ -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}
}
Expand Down Expand Up @@ -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}
}
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions skiplist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -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]()
Expand Down
9 changes: 9 additions & 0 deletions stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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]
Expand Down
Loading

0 comments on commit 7d4beb4

Please sign in to comment.