diff --git a/g/container/glist/glist.go b/g/container/glist/glist.go index cef9b7c01..fa0361702 100644 --- a/g/container/glist/glist.go +++ b/g/container/glist/glist.go @@ -209,7 +209,7 @@ func (l *List) Len() (length int) { return } -// Alias of Len. +// Size is alias of Len. func (l *List) Size() int { return l.Len() } diff --git a/g/container/glist/glist_z_unit_test.go b/g/container/glist/glist_z_unit_test.go index 7cd55dd15..c726e9c29 100644 --- a/g/container/glist/glist_z_unit_test.go +++ b/g/container/glist/glist_z_unit_test.go @@ -7,361 +7,577 @@ package glist import ( - "container/list" - "testing" + "container/list" + "github.com/gogf/gf/g/test/gtest" + "github.com/gogf/gf/g/util/gconv" + + "testing" ) // 检查链表长度 func checkListLen(t *testing.T, l *List, len int) bool { - if n := l.Len(); n != len { - t.Errorf("l.Len() = %d, want %d", n, len) - return false - } - return true + if n := l.Len(); n != len { + t.Errorf("l.Len() = %d, want %d", n, len) + return false + } + return true } // 检查指针地址 func checkListPointers(t *testing.T, l *List, es []*Element) { - if !checkListLen(t, l, len(es)) { - return - } - l.RLockFunc(func(list *list.List) { - for i, e := 0, l.list.Front(); i < list.Len(); i, e = i + 1, e.Next() { - if e.Prev() != es[i].Prev() { - t.Errorf("list[%d].Prev = %p, want %p", i, e.Prev(), es[i].Prev()) - } - if e.Next() != es[i].Next() { - t.Errorf("list[%d].Next = %p, want %p", i, e.Next(), es[i].Next()) - } - } - }) + if !checkListLen(t, l, len(es)) { + return + } + l.RLockFunc(func(list *list.List) { + for i, e := 0, l.list.Front(); i < list.Len(); i, e = i+1, e.Next() { + if e.Prev() != es[i].Prev() { + t.Errorf("list[%d].Prev = %p, want %p", i, e.Prev(), es[i].Prev()) + } + if e.Next() != es[i].Next() { + t.Errorf("list[%d].Next = %p, want %p", i, e.Next(), es[i].Next()) + } + } + }) } func TestBasic(t *testing.T) { - l := New() - l.PushFront(1) - l.PushFront(2) - if v := l.PopBack(); v != 1 { - t.Errorf("EXPECT %v, GOT %v", 1, v) - } else { - //fmt.Println(v) - } - if v := l.PopBack(); v != 2 { - t.Errorf("EXPECT %v, GOT %v", 2, v) - } else { - //fmt.Println(v) - } - if v := l.PopBack(); v != nil { - t.Errorf("EXPECT %v, GOT %v", nil, v) - } else { - //fmt.Println(v) - } - l.PushBack(1) - l.PushBack(2) - if v := l.PopFront(); v != 1 { - t.Errorf("EXPECT %v, GOT %v", 1, v) - } else { - //fmt.Println(v) - } - if v := l.PopFront(); v != 2 { - t.Errorf("EXPECT %v, GOT %v", 2, v) - } else { - //fmt.Println(v) - } - if v := l.PopFront(); v != nil { - t.Errorf("EXPECT %v, GOT %v", nil, v) - } else { - //fmt.Println(v) - } + l := New() + l.PushFront(1) + l.PushFront(2) + if v := l.PopBack(); v != 1 { + t.Errorf("EXPECT %v, GOT %v", 1, v) + } else { + //fmt.Println(v) + } + if v := l.PopBack(); v != 2 { + t.Errorf("EXPECT %v, GOT %v", 2, v) + } else { + //fmt.Println(v) + } + if v := l.PopBack(); v != nil { + t.Errorf("EXPECT %v, GOT %v", nil, v) + } else { + //fmt.Println(v) + } + l.PushBack(1) + l.PushBack(2) + if v := l.PopFront(); v != 1 { + t.Errorf("EXPECT %v, GOT %v", 1, v) + } else { + //fmt.Println(v) + } + if v := l.PopFront(); v != 2 { + t.Errorf("EXPECT %v, GOT %v", 2, v) + } else { + //fmt.Println(v) + } + if v := l.PopFront(); v != nil { + t.Errorf("EXPECT %v, GOT %v", nil, v) + } else { + //fmt.Println(v) + } } func TestList(t *testing.T) { - l := New() - checkListPointers(t, l, []*Element{}) + l := New() + checkListPointers(t, l, []*Element{}) - // Single element list - e := l.PushFront("a") - checkListPointers(t, l, []*Element{e}) - l.MoveToFront(e) - checkListPointers(t, l, []*Element{e}) - l.MoveToBack(e) - checkListPointers(t, l, []*Element{e}) - l.Remove(e) - checkListPointers(t, l, []*Element{}) + // Single element list + e := l.PushFront("a") + checkListPointers(t, l, []*Element{e}) + l.MoveToFront(e) + checkListPointers(t, l, []*Element{e}) + l.MoveToBack(e) + checkListPointers(t, l, []*Element{e}) + l.Remove(e) + checkListPointers(t, l, []*Element{}) - // Bigger list - e2 := l.PushFront(2) - e1 := l.PushFront(1) - e3 := l.PushBack(3) - e4 := l.PushBack("banana") - checkListPointers(t, l, []*Element{e1, e2, e3, e4}) + // Bigger list + e2 := l.PushFront(2) + e1 := l.PushFront(1) + e3 := l.PushBack(3) + e4 := l.PushBack("banana") + checkListPointers(t, l, []*Element{e1, e2, e3, e4}) - l.Remove(e2) - checkListPointers(t, l, []*Element{e1, e3, e4}) + l.Remove(e2) + checkListPointers(t, l, []*Element{e1, e3, e4}) - l.MoveToFront(e3) // move from middle - checkListPointers(t, l, []*Element{e3, e1, e4}) + l.MoveToFront(e3) // move from middle + checkListPointers(t, l, []*Element{e3, e1, e4}) - l.MoveToFront(e1) - l.MoveToBack(e3) // move from middle - checkListPointers(t, l, []*Element{e1, e4, e3}) + l.MoveToFront(e1) + l.MoveToBack(e3) // move from middle + checkListPointers(t, l, []*Element{e1, e4, e3}) - l.MoveToFront(e3) // move from back - checkListPointers(t, l, []*Element{e3, e1, e4}) - l.MoveToFront(e3) // should be no-op - checkListPointers(t, l, []*Element{e3, e1, e4}) + l.MoveToFront(e3) // move from back + checkListPointers(t, l, []*Element{e3, e1, e4}) + l.MoveToFront(e3) // should be no-op + checkListPointers(t, l, []*Element{e3, e1, e4}) - l.MoveToBack(e3) // move from front - checkListPointers(t, l, []*Element{e1, e4, e3}) - l.MoveToBack(e3) // should be no-op - checkListPointers(t, l, []*Element{e1, e4, e3}) + l.MoveToBack(e3) // move from front + checkListPointers(t, l, []*Element{e1, e4, e3}) + l.MoveToBack(e3) // should be no-op + checkListPointers(t, l, []*Element{e1, e4, e3}) - e2 = l.InsertBefore(2, e1) // insert before front - checkListPointers(t, l, []*Element{e2, e1, e4, e3}) - l.Remove(e2) - e2 = l.InsertBefore(2, e4) // insert before middle - checkListPointers(t, l, []*Element{e1, e2, e4, e3}) - l.Remove(e2) - e2 = l.InsertBefore(2, e3) // insert before back - checkListPointers(t, l, []*Element{e1, e4, e2, e3}) - l.Remove(e2) + e2 = l.InsertBefore(2, e1) // insert before front + checkListPointers(t, l, []*Element{e2, e1, e4, e3}) + l.Remove(e2) + e2 = l.InsertBefore(2, e4) // insert before middle + checkListPointers(t, l, []*Element{e1, e2, e4, e3}) + l.Remove(e2) + e2 = l.InsertBefore(2, e3) // insert before back + checkListPointers(t, l, []*Element{e1, e4, e2, e3}) + l.Remove(e2) - e2 = l.InsertAfter(2, e1) // insert after front - checkListPointers(t, l, []*Element{e1, e2, e4, e3}) - l.Remove(e2) - e2 = l.InsertAfter(2, e4) // insert after middle - checkListPointers(t, l, []*Element{e1, e4, e2, e3}) - l.Remove(e2) - e2 = l.InsertAfter(2, e3) // insert after back - checkListPointers(t, l, []*Element{e1, e4, e3, e2}) - l.Remove(e2) + e2 = l.InsertAfter(2, e1) // insert after front + checkListPointers(t, l, []*Element{e1, e2, e4, e3}) + l.Remove(e2) + e2 = l.InsertAfter(2, e4) // insert after middle + checkListPointers(t, l, []*Element{e1, e4, e2, e3}) + l.Remove(e2) + e2 = l.InsertAfter(2, e3) // insert after back + checkListPointers(t, l, []*Element{e1, e4, e3, e2}) + l.Remove(e2) - // Check standard iteration. - sum := 0 - for e := l.Front(); e != nil; e = e.Next() { - if i, ok := e.Value.(int); ok { - sum += i - } - } - if sum != 4 { - t.Errorf("sum over l = %d, want 4", sum) - } + // Check standard iteration. + sum := 0 + for e := l.Front(); e != nil; e = e.Next() { + if i, ok := e.Value.(int); ok { + sum += i + } + } + if sum != 4 { + t.Errorf("sum over l = %d, want 4", sum) + } - // Clear all elements by iterating - var next *Element - for e := l.Front(); e != nil; e = next { - next = e.Next() - l.Remove(e) - } - checkListPointers(t, l, []*Element{}) + // Clear all elements by iterating + var next *Element + for e := l.Front(); e != nil; e = next { + next = e.Next() + l.Remove(e) + } + checkListPointers(t, l, []*Element{}) } func checkList(t *testing.T, l *List, es []interface{}) { - if !checkListLen(t, l, len(es)) { - return - } + if !checkListLen(t, l, len(es)) { + return + } - i := 0 - for e := l.Front(); e != nil; e = e.Next() { - le := e.Value.(int) - if le != es[i] { - t.Errorf("elt[%d].Value() = %v, want %v", i, le, es[i]) - } - i++ - } + i := 0 + for e := l.Front(); e != nil; e = e.Next() { + + switch e.Value.(type) { + case int: + if le := e.Value.(int); le != es[i] { + t.Errorf("elt[%d].Value() = %v, want %v", i, le, es[i]) + } + // default string + default: + if le := e.Value.(string); le != es[i] { + t.Errorf("elt[%v].Value() = %v, want %v", i, le, es[i]) + } + } + + i++ + } + + //for e := l.Front(); e != nil; e = e.Next() { + // le := e.Value.(int) + // if le != es[i] { + // t.Errorf("elt[%d].Value() = %v, want %v", i, le, es[i]) + // } + // i++ + //} } func TestExtending(t *testing.T) { - l1 := New() - l2 := New() + l1 := New() + l2 := New() - l1.PushBack(1) - l1.PushBack(2) - l1.PushBack(3) + l1.PushBack(1) + l1.PushBack(2) + l1.PushBack(3) - l2.PushBack(4) - l2.PushBack(5) + l2.PushBack(4) + l2.PushBack(5) - l3 := New() - l3.PushBackList(l1) - checkList(t, l3, []interface{}{1, 2, 3}) - l3.PushBackList(l2) - checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) + l3 := New() + l3.PushBackList(l1) + checkList(t, l3, []interface{}{1, 2, 3}) + l3.PushBackList(l2) + checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) - l3 = New() - l3.PushFrontList(l2) - checkList(t, l3, []interface{}{4, 5}) - l3.PushFrontList(l1) - checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) + l3 = New() + l3.PushFrontList(l2) + checkList(t, l3, []interface{}{4, 5}) + l3.PushFrontList(l1) + checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) - checkList(t, l1, []interface{}{1, 2, 3}) - checkList(t, l2, []interface{}{4, 5}) + checkList(t, l1, []interface{}{1, 2, 3}) + checkList(t, l2, []interface{}{4, 5}) - l3 = New() - l3.PushBackList(l1) - checkList(t, l3, []interface{}{1, 2, 3}) - l3.PushBackList(l3) - checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) + l3 = New() + l3.PushBackList(l1) + checkList(t, l3, []interface{}{1, 2, 3}) + l3.PushBackList(l3) + checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) - l3 = New() - l3.PushFrontList(l1) - checkList(t, l3, []interface{}{1, 2, 3}) - l3.PushFrontList(l3) - checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) + l3 = New() + l3.PushFrontList(l1) + checkList(t, l3, []interface{}{1, 2, 3}) + l3.PushFrontList(l3) + checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) - l3 = New() - l1.PushBackList(l3) - checkList(t, l1, []interface{}{1, 2, 3}) - l1.PushFrontList(l3) - checkList(t, l1, []interface{}{1, 2, 3}) + l3 = New() + l1.PushBackList(l3) + checkList(t, l1, []interface{}{1, 2, 3}) + l1.PushFrontList(l3) + checkList(t, l1, []interface{}{1, 2, 3}) } func TestRemove(t *testing.T) { - l := New() - e1 := l.PushBack(1) - e2 := l.PushBack(2) - checkListPointers(t, l, []*Element{e1, e2}) - //e := l.Front() - //l.Remove(e) - //checkListPointers(t, l, []*Element{e2}) - //l.Remove(e) - //checkListPointers(t, l, []*Element{e2}) + l := New() + e1 := l.PushBack(1) + e2 := l.PushBack(2) + checkListPointers(t, l, []*Element{e1, e2}) + //e := l.Front() + //l.Remove(e) + //checkListPointers(t, l, []*Element{e2}) + //l.Remove(e) + //checkListPointers(t, l, []*Element{e2}) } func TestIssue4103(t *testing.T) { - l1 := New() - l1.PushBack(1) - l1.PushBack(2) + l1 := New() + l1.PushBack(1) + l1.PushBack(2) - l2 := New() - l2.PushBack(3) - l2.PushBack(4) + l2 := New() + l2.PushBack(3) + l2.PushBack(4) - e := l1.Front() - l2.Remove(e) // l2 should not change because e is not an element of l2 - if n := l2.Len(); n != 2 { - t.Errorf("l2.Len() = %d, want 2", n) - } + e := l1.Front() + l2.Remove(e) // l2 should not change because e is not an element of l2 + if n := l2.Len(); n != 2 { + t.Errorf("l2.Len() = %d, want 2", n) + } - l1.InsertBefore(8, e) - if n := l1.Len(); n != 3 { - t.Errorf("l1.Len() = %d, want 3", n) - } + l1.InsertBefore(8, e) + if n := l1.Len(); n != 3 { + t.Errorf("l1.Len() = %d, want 3", n) + } } func TestIssue6349(t *testing.T) { - l := New() - l.PushBack(1) - l.PushBack(2) + l := New() + l.PushBack(1) + l.PushBack(2) - e := l.Front() - l.Remove(e) - if e.Value != 1 { - t.Errorf("e.value = %d, want 1", e.Value) - } - //if e.Next() != nil { - // t.Errorf("e.Next() != nil") - //} - //if e.Prev() != nil { - // t.Errorf("e.Prev() != nil") - //} + e := l.Front() + l.Remove(e) + if e.Value != 1 { + t.Errorf("e.value = %d, want 1", e.Value) + } + //if e.Next() != nil { + // t.Errorf("e.Next() != nil") + //} + //if e.Prev() != nil { + // t.Errorf("e.Prev() != nil") + //} } func TestMove(t *testing.T) { - l := New() - e1 := l.PushBack(1) - e2 := l.PushBack(2) - e3 := l.PushBack(3) - e4 := l.PushBack(4) + l := New() + e1 := l.PushBack(1) + e2 := l.PushBack(2) + e3 := l.PushBack(3) + e4 := l.PushBack(4) - l.MoveAfter(e3, e3) - checkListPointers(t, l, []*Element{e1, e2, e3, e4}) - l.MoveBefore(e2, e2) - checkListPointers(t, l, []*Element{e1, e2, e3, e4}) + l.MoveAfter(e3, e3) + checkListPointers(t, l, []*Element{e1, e2, e3, e4}) + l.MoveBefore(e2, e2) + checkListPointers(t, l, []*Element{e1, e2, e3, e4}) - l.MoveAfter(e3, e2) - checkListPointers(t, l, []*Element{e1, e2, e3, e4}) - l.MoveBefore(e2, e3) - checkListPointers(t, l, []*Element{e1, e2, e3, e4}) + l.MoveAfter(e3, e2) + checkListPointers(t, l, []*Element{e1, e2, e3, e4}) + l.MoveBefore(e2, e3) + checkListPointers(t, l, []*Element{e1, e2, e3, e4}) - l.MoveBefore(e2, e4) - checkListPointers(t, l, []*Element{e1, e3, e2, e4}) - e2, e3 = e3, e2 + l.MoveBefore(e2, e4) + checkListPointers(t, l, []*Element{e1, e3, e2, e4}) + e2, e3 = e3, e2 - l.MoveBefore(e4, e1) - checkListPointers(t, l, []*Element{e4, e1, e2, e3}) - e1, e2, e3, e4 = e4, e1, e2, e3 + l.MoveBefore(e4, e1) + checkListPointers(t, l, []*Element{e4, e1, e2, e3}) + e1, e2, e3, e4 = e4, e1, e2, e3 - l.MoveAfter(e4, e1) - checkListPointers(t, l, []*Element{e1, e4, e2, e3}) - e2, e3, e4 = e4, e2, e3 + l.MoveAfter(e4, e1) + checkListPointers(t, l, []*Element{e1, e4, e2, e3}) + e2, e3, e4 = e4, e2, e3 - l.MoveAfter(e2, e3) - checkListPointers(t, l, []*Element{e1, e3, e2, e4}) - e2, e3 = e3, e2 + l.MoveAfter(e2, e3) + checkListPointers(t, l, []*Element{e1, e3, e2, e4}) + e2, e3 = e3, e2 } // Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List func TestZeroList(t *testing.T) { - var l1 = New() - l1.PushFront(1) - checkList(t, l1, []interface{}{1}) + var l1 = New() + l1.PushFront(1) + checkList(t, l1, []interface{}{1}) - var l2 = New() - l2.PushBack(1) - checkList(t, l2, []interface{}{1}) + var l2 = New() + l2.PushBack(1) + checkList(t, l2, []interface{}{1}) - var l3 = New() - l3.PushFrontList(l1) - checkList(t, l3, []interface{}{1}) + var l3 = New() + l3.PushFrontList(l1) + checkList(t, l3, []interface{}{1}) - var l4 = New() - l4.PushBackList(l2) - checkList(t, l4, []interface{}{1}) + var l4 = New() + l4.PushBackList(l2) + checkList(t, l4, []interface{}{1}) } // Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l. func TestInsertBeforeUnknownMark(t *testing.T) { - l := New() - l.PushBack(1) - l.PushBack(2) - l.PushBack(3) - l.InsertBefore(1, new(Element)) - checkList(t, l, []interface{}{1, 2, 3}) + l := New() + l.PushBack(1) + l.PushBack(2) + l.PushBack(3) + l.InsertBefore(1, new(Element)) + checkList(t, l, []interface{}{1, 2, 3}) } // Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l. func TestInsertAfterUnknownMark(t *testing.T) { - l := New() - l.PushBack(1) - l.PushBack(2) - l.PushBack(3) - l.InsertAfter(1, new(Element)) - checkList(t, l, []interface{}{1, 2, 3}) + l := New() + l.PushBack(1) + l.PushBack(2) + l.PushBack(3) + l.InsertAfter(1, new(Element)) + checkList(t, l, []interface{}{1, 2, 3}) } // Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l. func TestMoveUnknownMark(t *testing.T) { - l1 := New() - e1 := l1.PushBack(1) + l1 := New() + e1 := l1.PushBack(1) - l2 := New() - e2 := l2.PushBack(2) + l2 := New() + e2 := l2.PushBack(2) - l1.MoveAfter(e1, e2) - checkList(t, l1, []interface{}{1}) - checkList(t, l2, []interface{}{2}) + l1.MoveAfter(e1, e2) + checkList(t, l1, []interface{}{1}) + checkList(t, l2, []interface{}{2}) - l1.MoveBefore(e1, e2) - checkList(t, l1, []interface{}{1}) - checkList(t, l2, []interface{}{2}) + l1.MoveBefore(e1, e2) + checkList(t, l1, []interface{}{1}) + checkList(t, l2, []interface{}{2}) } func TestList_RemoveAll(t *testing.T) { - l := New() - l.PushBack(1) - l.RemoveAll() - checkList(t, l, []interface{}{}) - l.PushBack(2) - checkList(t, l, []interface{}{2}) -} \ No newline at end of file + l := New() + l.PushBack(1) + l.RemoveAll() + checkList(t, l, []interface{}{}) + l.PushBack(2) + checkList(t, l, []interface{}{2}) +} + +func TestList_PushFronts(t *testing.T) { + l := New() + a1 := []interface{}{1, 2} + l.PushFronts(a1) + checkList(t, l, []interface{}{2, 1}) + a1 = []interface{}{3, 4, 5} + l.PushFronts(a1) + checkList(t, l, []interface{}{5, 4, 3, 2, 1}) +} + +func TestList_PushBacks(t *testing.T) { + l := New() + a1 := []interface{}{1, 2} + l.PushBacks(a1) + checkList(t, l, []interface{}{1, 2}) + a1 = []interface{}{3, 4, 5} + l.PushBacks(a1) + checkList(t, l, []interface{}{1, 2, 3, 4, 5}) +} + +func TestList_PopBacks(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + a2 := []interface{}{"a", "c", "b", "e"} + l.PushFronts(a1) + i1 := l.PopBacks(2) + gtest.Assert(i1, []interface{}{"1", "2"}) + + l.PushBacks(a2) //4.3,a,c,b,e + i1 = l.PopBacks(3) + gtest.Assert(i1, []interface{}{"e", "b", "c"}) + +} + +func TestList_PopFronts(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.PopFronts(2) + gtest.Assert(i1, []interface{}{"4", "3"}) + gtest.Assert(l.Len(), 2) +} + +func TestList_PopBackAll(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.PopBackAll() + gtest.Assert(i1, []interface{}{1, 2, 3, 4}) + gtest.Assert(l.Len(), 0) + +} + +func TestList_PopFrontAll(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.PopFrontAll() + gtest.Assert(i1, []interface{}{4, 3, 2, 1}) + gtest.Assert(l.Len(), 0) +} + +func TestList_FrontAll(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.FrontAll() + gtest.Assert(i1, []interface{}{4, 3, 2, 1}) + gtest.Assert(l.Len(), 4) +} + +func TestList_BackAll(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.BackAll() + gtest.Assert(i1, []interface{}{1, 2, 3, 4}) + gtest.Assert(l.Len(), 4) +} + +func TestList_FrontValue(t *testing.T) { + l := New() + l2 := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.FrontValue() + gtest.Assert(gconv.Int(i1), 4) + gtest.Assert(l.Len(), 4) + + i1 = l2.FrontValue() + gtest.Assert(i1, nil) +} + +func TestList_BackValue(t *testing.T) { + l := New() + l2 := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + i1 := l.BackValue() + gtest.Assert(gconv.Int(i1), 1) + gtest.Assert(l.Len(), 4) + + i1 = l2.FrontValue() + gtest.Assert(i1, nil) + +} + +func TestList_Back(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + e1 := l.Back() + gtest.Assert(e1.Value, 1) + gtest.Assert(l.Len(), 4) +} + +func TestList_Size(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + gtest.Assert(l.Size(), 4) + l.PopFront() + gtest.Assert(l.Size(), 3) +} + +func TestList_Removes(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + e1 := l.Back() + l.Removes([]*Element{e1}) + gtest.Assert(l.Len(), 3) + + e2 := l.Back() + l.Removes([]*Element{e2}) + gtest.Assert(l.Len(), 2) + checkList(t, l, []interface{}{4, 3}) + +} + +func TestList_Clear(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + l.Clear() + gtest.Assert(l.Len(), 0) +} + +func TestList_IteratorAsc(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 5, 6, 3, 4} + l.PushFronts(a1) + e1 := l.Back() + fun1 := func(e *Element) bool { + if gconv.Int(e1.Value) > 2 { + return true + } + return false + } + checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1}) + l.IteratorAsc(fun1) + checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1}) +} + +func TestList_IteratorDesc(t *testing.T) { + l := New() + a1 := []interface{}{1, 2, 3, 4} + l.PushFronts(a1) + e1 := l.Back() + fun1 := func(e *Element) bool { + if gconv.Int(e1.Value) > 6 { + return true + } + return false + } + l.IteratorDesc(fun1) + gtest.Assert(l.Len(), 4) + checkList(t, l, []interface{}{4, 3, 2, 1}) +} + +func TestList_Iterator(t *testing.T) { + l := New() + a1 := []interface{}{"a", "b", "c", "d", "e"} + l.PushFronts(a1) + e1 := l.Back() + fun1 := func(e *Element) bool { + if gconv.String(e1.Value) > "c" { + return true + } + return false + } + checkList(t, l, []interface{}{"e", "d", "c", "b", "a"}) + l.Iterator(fun1) + checkList(t, l, []interface{}{"e", "d", "c", "b", "a"}) +} diff --git a/g/container/gqueue/gqueue.go b/g/container/gqueue/gqueue.go index 9ec7b12c7..eb4b2a340 100644 --- a/g/container/gqueue/gqueue.go +++ b/g/container/gqueue/gqueue.go @@ -110,9 +110,16 @@ func (q *Queue) Close() { close(q.closed) } -// Size returns the length of the queue. -func (q *Queue) Size() int { - return len(q.C) + q.list.Len() +// Len returns the length of the queue. +func (q *Queue) Len() (length int) { + if q.list != nil { + length += q.list.Len() + } + length += len(q.C) + return } - +// Size is alias of Len. +func (q *Queue) Size() int { + return q.Len() +} diff --git a/g/container/gtree/gtree_avltree.go b/g/container/gtree/gtree_avltree.go index 18ff542b5..23ba935f1 100644 --- a/g/container/gtree/gtree_avltree.go +++ b/g/container/gtree/gtree_avltree.go @@ -29,7 +29,7 @@ type AVLTreeNode struct { b int8 } -// NewAVLTree instantiates an AVL tree with the custom comparator. +// NewAVLTree instantiates an AVL tree with the custom key comparator. // The parameter used to specify whether using tree in un-concurrent-safety, // which is false in default. func NewAVLTree(comparator func(v1, v2 interface{}) int, unsafe...bool) *AVLTree { @@ -39,7 +39,7 @@ func NewAVLTree(comparator func(v1, v2 interface{}) int, unsafe...bool) *AVLTree } } -// NewAVLTreeFrom instantiates an AVL tree with the custom comparator and data map. +// NewAVLTreeFrom instantiates an AVL tree with the custom key comparator and data map. // The parameter used to specify whether using tree in un-concurrent-safety, // which is false in default. func NewAVLTreeFrom(comparator func(v1, v2 interface{}) int, data map[interface{}]interface{}, unsafe...bool) *AVLTree { @@ -222,7 +222,7 @@ func (tree *AVLTree) Contains(key interface{}) bool { return ok } -// Remove remove the node from the tree by key. +// Remove removes the node from the tree by key. // Key should adhere to the comparator's type assertion, otherwise method panics. func (tree *AVLTree) Remove(key interface{}) (value interface{}) { tree.mu.Lock() @@ -306,7 +306,7 @@ func (tree *AVLTree) Right() *AVLTreeNode { return node } -// Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found. +// Floor Finds floor node of the input key, return the floor node or nil if no floor node is found. // Second return parameter is true if floor was found, otherwise false. // // Floor node is defined as the largest node that is smaller than or equal to the given node. @@ -317,16 +317,15 @@ func (tree *AVLTree) Right() *AVLTreeNode { func (tree *AVLTree) Floor(key interface{}) (floor *AVLTreeNode, found bool) { tree.mu.RLock() defer tree.mu.RUnlock() - found = false n := tree.root for n != nil { c := tree.comparator(key, n.Key) switch { - case c == 0: return n, true - case c < 0: n = n.children[0] - case c > 0: - floor, found = n, true - n = n.children[1] + case c == 0: return n, true + case c < 0: n = n.children[0] + case c > 0: + floor, found = n, true + n = n.children[1] } } if found { @@ -335,7 +334,7 @@ func (tree *AVLTree) Floor(key interface{}) (floor *AVLTreeNode, found bool) { return nil, false } -// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found. +// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling node is found. // Second return parameter is true if ceiling was found, otherwise false. // // Ceiling node is defined as the smallest node that is larger than or equal to the given node. @@ -346,7 +345,6 @@ func (tree *AVLTree) Floor(key interface{}) (floor *AVLTreeNode, found bool) { func (tree *AVLTree) Ceiling(key interface{}) (ceiling *AVLTreeNode, found bool) { tree.mu.RLock() defer tree.mu.RUnlock() - found = false n := tree.root for n != nil { c := tree.comparator(key, n.Key) @@ -514,7 +512,7 @@ func (tree *AVLTree) remove(key interface{}, qp **AVLTreeNode) (value interface{ if fix { return value, removeFix(int8(-c), qp) } - return nil, false + return value, false } func removeMin(qp **AVLTreeNode, minKey *interface{}, minVal *interface{}) bool { diff --git a/g/container/gtree/gtree_btree.go b/g/container/gtree/gtree_btree.go index de4546cca..34f375257 100644 --- a/g/container/gtree/gtree_btree.go +++ b/g/container/gtree/gtree_btree.go @@ -503,9 +503,9 @@ func (tree *BTree) isLeaf(node *BTreeNode) bool { return len(node.Children) == 0 } -func (tree *BTree) isFull(node *BTreeNode) bool { - return len(node.Entries) == tree.maxEntries() -} +//func (tree *BTree) isFull(node *BTreeNode) bool { +// return len(node.Entries) == tree.maxEntries() +//} func (tree *BTree) shouldSplit(node *BTreeNode) bool { return len(node.Entries) > tree.maxEntries() diff --git a/g/container/gtree/gtree_redblacktree.go b/g/container/gtree/gtree_redblacktree.go index 064b1ac63..cc4cdd82a 100644 --- a/g/container/gtree/gtree_redblacktree.go +++ b/g/container/gtree/gtree_redblacktree.go @@ -36,7 +36,7 @@ type RedBlackTreeNode struct { parent *RedBlackTreeNode } -// NewRedBlackTree instantiates a red-black tree with the custom comparator. +// NewRedBlackTree instantiates a red-black tree with the custom key comparator. // The parameter used to specify whether using tree in un-concurrent-safety, // which is false in default. func NewRedBlackTree(comparator func(v1, v2 interface{}) int, unsafe...bool) *RedBlackTree { @@ -46,7 +46,7 @@ func NewRedBlackTree(comparator func(v1, v2 interface{}) int, unsafe...bool) *Re } } -// NewRedBlackTreeFrom instantiates a red-black tree with the custom comparator and map. +// NewRedBlackTreeFrom instantiates a red-black tree with the custom key comparator and map. // The parameter used to specify whether using tree in un-concurrent-safety, // which is false in default. func NewRedBlackTreeFrom(comparator func(v1, v2 interface{}) int, data map[interface{}]interface{}, unsafe...bool) *RedBlackTree { @@ -393,60 +393,56 @@ func (tree *RedBlackTree) rightNode() *RedBlackTreeNode { return p } -// Floor Finds floor node of the input , return the floor node or nil if no floor is found. +// Floor Finds floor node of the input key, return the floor node or nil if no floor node is found. +// Second return parameter is true if floor was found, otherwise false. // // Floor node is defined as the largest node that its key is smaller than or equal to the given . // A floor node may not be found, either because the tree is empty, or because // all nodes in the tree are larger than the given node. -func (tree *RedBlackTree) Floor(key interface{}) (floor *RedBlackTreeNode) { +func (tree *RedBlackTree) Floor(key interface{}) (floor *RedBlackTreeNode, found bool) { tree.mu.RLock() defer tree.mu.RUnlock() - found := false - node := tree.root - for node != nil { - compare := tree.comparator(key, node.Key) + n := tree.root + for n != nil { + compare := tree.comparator(key, n.Key) switch { - case compare == 0: - return node - case compare < 0: - node = node.left - case compare > 0: - floor, found = node, true - node = node.right + case compare == 0: return n, true + case compare < 0: n = n.left + case compare > 0: + floor, found = n, true + n = n.right } } if found { - return floor + return } - return nil + return nil, false } -// Ceiling finds ceiling node of the input , return the ceiling node or nil if no ceiling is found. +// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling node is found. +// Second return parameter is true if ceiling was found, otherwise false. // // Ceiling node is defined as the smallest node that its key is larger than or equal to the given . // A ceiling node may not be found, either because the tree is empty, or because // all nodes in the tree are smaller than the given node. -func (tree *RedBlackTree) Ceiling(key interface{}) (ceiling *RedBlackTreeNode) { +func (tree *RedBlackTree) Ceiling(key interface{}) (ceiling *RedBlackTreeNode, found bool) { tree.mu.RLock() defer tree.mu.RUnlock() - found := false - node := tree.root - for node != nil { - compare := tree.comparator(key, node.Key) + n := tree.root + for n != nil { + compare := tree.comparator(key, n.Key) switch { - case compare == 0: - return node - case compare < 0: - ceiling, found = node, true - node = node.left - case compare > 0: - node = node.right + case compare == 0: return n, true + case compare > 0: n = n.right + case compare < 0: + ceiling, found = n, true + n = n.left } } if found { - return ceiling + return } - return nil + return nil, false } // Iterator is alias of IteratorAsc. diff --git a/geg/other/test.go b/geg/other/test.go index 125e7e362..49c122b37 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,24 +1,14 @@ package main import ( -<<<<<<< HEAD - "fmt" + "github.com/gogf/gf/g/container/gqueue" + "github.com/gogf/gf/g/test/gtest" ) func main() { - var i float64 = 0 - for index := 0; index < 10; index++ { - i += 0.1 - fmt.Println(i) - } + q1 := gqueue.New(2) + q1.Push(1) + q1.Push(2) + gtest.Assert(q1.Size(),2) } -======= - "github.com/gogf/gf/g/encoding/gjson" -) -func main() { - j := gjson.New(`[1,2,3]`) - j.Remove("1") - j.Dump() -} ->>>>>>> master