From ed02794b0499a9730ceeb379897aec22df9fc5b0 Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Fri, 20 May 2022 17:17:31 +0800 Subject: [PATCH] create --- collections/linked_list.go | 2 + collections/list.go | 2 + collections/queue.go | 13 +--- collections/stack.go | 1 + errors/error_test.go | 140 +++++++++++++++++++++++++++++++++++++ tree/bptree.go | 90 ++++++++++++++++++++++++ tree/bptree_test.go | 2 + tree/btree.go | 112 +++++++++++++++++++++++++++++ tree/btree_test.go | 15 ++++ tree/rbtree.go | 42 +++++++++++ tree/tree.go | 28 ++++++++ 11 files changed, 436 insertions(+), 11 deletions(-) create mode 100644 collections/linked_list.go create mode 100644 errors/error_test.go create mode 100644 tree/bptree.go create mode 100644 tree/bptree_test.go create mode 100644 tree/btree.go create mode 100644 tree/btree_test.go create mode 100644 tree/rbtree.go create mode 100644 tree/tree.go diff --git a/collections/linked_list.go b/collections/linked_list.go new file mode 100644 index 0000000..2337a02 --- /dev/null +++ b/collections/linked_list.go @@ -0,0 +1,2 @@ +package collections + diff --git a/collections/list.go b/collections/list.go index 9032cb3..059f9b1 100644 --- a/collections/list.go +++ b/collections/list.go @@ -1,5 +1,6 @@ package collections +// 列表 type List[T any] interface { Add(T) Delete(T) @@ -7,6 +8,7 @@ type List[T any] interface { ToSlice() []T } +// 队列 type Queue[T any] interface { Put(T) Poll() T diff --git a/collections/queue.go b/collections/queue.go index 36644ed..20a1a26 100644 --- a/collections/queue.go +++ b/collections/queue.go @@ -40,21 +40,12 @@ func (q *ArrayQueue[T]) Poll() T { // 队列最前面元素 v := q.array[0] - /* 直接原位移动,但缩容后继的空间不会被释放 - for i := 1; i < queue.size; i++ { - // 从第一位开始进行数据移动 - queue.array[i-1] = queue.array[i] - } - // 原数组缩容 - queue.array = queue.array[0 : queue.size-1] - */ - // 创建新的数组,移动次数过多 newArray := make([]T, q.size-1) for i := 1; i < q.size; i++ { - // 从老数组的第一位开始进行数据移动 - newArray[i-1] = q.array[i] + copy(newArray, q.array[1:]) } + q.array = newArray // 队中元素数量-1 diff --git a/collections/stack.go b/collections/stack.go index 6cf5807..1a82000 100644 --- a/collections/stack.go +++ b/collections/stack.go @@ -15,6 +15,7 @@ type ArrayStack[T any] struct { lock sync.Mutex // 为了并发安全使用的锁 } +// 初始化堆栈 func NewArrayStack[T any]() *ArrayStack[T] { return &ArrayStack[T]{} } diff --git a/errors/error_test.go b/errors/error_test.go new file mode 100644 index 0000000..410bd3c --- /dev/null +++ b/errors/error_test.go @@ -0,0 +1,140 @@ +package errors_test + +import ( + "fmt" + "runtime" + "testing" + + "github.com/charlienet/go-mixed/errors" + pkgerr "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +const ( + defaultErrorCode = "999999" + testCode = "0093832" +) + +var ( + globalError = errors.Error(defaultErrorCode, "全局错误对象") + errorbyCode = errors.Error(testCode, "全局错误对象") +) + +func TestPersetError(t *testing.T) { + t.Log(globalError) + t.Log(errorbyCode) +} + +func TestWithCode(t *testing.T) { + code := "098765" + ne := globalError.WithCode(code) + + assert.Equal(t, code, ne.Code()) + assert.Equal(t, globalError.Code(), defaultErrorCode) +} + +func TestWithMessage(t *testing.T) { + se := errorbyCode.WithMessage("新的消息") + t.Log(se) + assert.Equal(t, testCode, se.Code()) +} + +func TestNewError(t *testing.T) { + var e error = errors.Error("123456", "测试") + + err := e.(*errors.CodeError) + t.Log(e, err.Code()) +} + +func TestNewWrapError(t *testing.T) { + err := errors.Wrapf(newError(), "33333", "测试") + t.Logf("%+v", err) +} + +func TestWithStack(t *testing.T) { + err := newError() + e := errors.Wrapf(err, "888888", "这是附加%s消息", "测试段") + t.Logf("%+v", e) +} + +func TestLogMessage(t *testing.T) { + t.Logf("%+v", errors.Error("88888", "错误消息")) + t.Log(errors.Error("77777")) + t.Log(errors.Error("77777", "测试")) +} + +func TestIs(t *testing.T) { + code1 := "000090" + code2 := "000091" + e1 := errors.Error(code1) + e2 := errors.Error(code1) + e3 := errors.Error(code2) + + t.Log(errors.Is(e1, e2)) + t.Log(errors.Is(e1, e3)) +} + +func TestAs(t *testing.T) { + sss := &errors.CodeError{} + ret := errors.As(globalError, sss) + t.Log(ret) +} + +func TestCause(t *testing.T) { + err := newError() + we := errors.Wrap(err, "22222") + + ue := errors.Cause(we) + t.Logf("%+v", ue) +} + +func TestCaller(t *testing.T) { + cc := c() + t.Logf("Caller:%+v", cc) +} + +type ErrorString struct { + s string +} + +func (e *ErrorString) Error() string { + return e.s +} + +func TestAs2(t *testing.T) { + var targetErr *ErrorString + err := fmt.Errorf("new error:[%w]", &ErrorString{s: "target err"}) + t.Log(errors.As(err, &targetErr)) + t.Log(targetErr) +} + +func c() *stack { + return caller() +} + +func caller() *stack { + const depth = 32 + var pcs [depth]uintptr + n := runtime.Callers(2, pcs[:]) + var st stack = pcs[0:n] + return &st +} + +type stack []uintptr + +func (s *stack) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case st.Flag('+'): + for _, pc := range *s { + f := pkgerr.Frame(pc) + fmt.Fprintf(st, "\n%+v", f) + } + } + } +} + +func newError() error { + return fmt.Errorf("原生错误信息") +} diff --git a/tree/bptree.go b/tree/bptree.go new file mode 100644 index 0000000..36d4c15 --- /dev/null +++ b/tree/bptree.go @@ -0,0 +1,90 @@ +package tree + +// B+ tree + +type BPTree[T Item[T]] struct { + length int + degree int +} + +// 初始化B+树 +func NewBPTree[T Item[T]](degree int) *BPTree[T] { + return &BPTree[T]{ + degree: degree, + } +} + +// nil cannot be added to the tree (will panic). +func (t *BPTree[T]) ReplaceOrInsert(item Item[T]) Item[T] { + return item +} + +func (t *BPTree[T]) Delete(item T) (T, bool) { + return *new(T), false +} + +func (t *BPTree[T]) Get(key T) (T, bool) { + return *new(T), false +} + +// Has returns true if the given key is in the tree. +func (t *BPTree[T]) Has(key T) bool { + return false +} + +// 升序 +func (t *BPTree[T]) Ascend(iterator ItemIterator[T]) { +} + +// 大于等于 +func (t *BPTree[T]) AscendGreaterOrEqual(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 小于 +func (t *BPTree[T]) AscendLessThan(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 范围迭代 +func (t *BPTree[T]) AscendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) { + +} + +// 降序升序迭代 +func (t *BPTree[T]) Descend(iterator ItemIterator[T]) { +} + +// 大于,降序迭代 +func (t *BPTree[T]) DescendGreaterThan(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 小于等于,降序迭代 +func (t *BPTree[T]) DescendLessOrEquql(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 范围降序迭代 +func (t *BPTree[T]) DescendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) { + +} + +func (t *BPTree[T]) Min() (T, bool) { + return *new(T), false +} + +func (t *BPTree[T]) Max() (T, bool) { + return *new(T), false +} + +func (t *BPTree[T]) Len() int { + return t.length +} + +func (t *BPTree[T]) Clear() { +} + +// B+ 树节点 +type bpNode[T Item[T]] struct { +} diff --git a/tree/bptree_test.go b/tree/bptree_test.go new file mode 100644 index 0000000..1c513f4 --- /dev/null +++ b/tree/bptree_test.go @@ -0,0 +1,2 @@ +package tree_test + diff --git a/tree/btree.go b/tree/btree.go new file mode 100644 index 0000000..1733db6 --- /dev/null +++ b/tree/btree.go @@ -0,0 +1,112 @@ +package tree + +import "sync" + +const ( + DefaultFreeListSize = 32 +) + +type FreeList[T Item[T]] struct { + mu sync.Mutex + freelist []*bNode[T] +} + +// 初始化B树 +type BTree[T Item[T]] struct { + degree int + length int + root *bNode[T] +} + +func NewBTree[T Item[T]](degree int) *BTree[T] { + return &BTree[T]{} +} + +// nil cannot be added to the tree (will panic). +func (t *BTree[T]) ReplaceOrInsert(item Item[T]) Item[T] { + return item +} + +func (t *BTree[T]) Delete(item T) (T, bool) { + return *new(T), false +} + +func (t *BTree[T]) Get(key T) (T, bool) { + return *new(T), false +} + +// Has returns true if the given key is in the tree. +func (t *BTree[T]) Has(key T) bool { + return false +} + +// 升序 +func (t *BTree[T]) Ascend(iterator ItemIterator[T]) { +} + +// 大于等于 +func (t *BTree[T]) AscendGreaterOrEqual(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 小于 +func (t *BTree[T]) AscendLessThan(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 范围迭代 +func (t *BTree[T]) AscendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) { + +} + +// 降序升序迭代 +func (t *BTree[T]) Descend(iterator ItemIterator[T]) { +} + +// 大于,降序迭代 +func (t *BTree[T]) DescendGreaterThan(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 小于等于,降序迭代 +func (t *BTree[T]) DescendLessOrEquql(pivot Item[T], iterator ItemIterator[T]) { + +} + +// 范围降序迭代 +func (t *BTree[T]) DescendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) { + +} + +func (t *BTree[T]) Min() (T, bool) { + return *new(T), false +} + +func (t *BTree[T]) Max() (T, bool) { + return *new(T), false +} + +func (t *BTree[T]) Len() int { + return t.length +} + +func (t *BTree[T]) Clear() { + +} + +// items stores items in a node. +type items[T Item[T]] []T + +// children stores child nodes in a node. +type children[T Item[T]] []*bNode[T] + +type copyOnWriteContext[T Item[T]] struct { + freelist *FreeList[T] +} + +// B树的内部节点 +type bNode[T Item[T]] struct { + items items[T] + children children[T] + cow *copyOnWriteContext[T] +} diff --git a/tree/btree_test.go b/tree/btree_test.go new file mode 100644 index 0000000..6d26b65 --- /dev/null +++ b/tree/btree_test.go @@ -0,0 +1,15 @@ +package tree + +import "testing" + +func TestNewBTree(t *testing.T) { + tr := NewBTree[Int](32) + + _ = tr +} + +type Int int + +func (a Int) Less(b Int) bool { + return a < b +} diff --git a/tree/rbtree.go b/tree/rbtree.go new file mode 100644 index 0000000..789d160 --- /dev/null +++ b/tree/rbtree.go @@ -0,0 +1,42 @@ +package tree + +type color uint + +const ( + RED color = 0 + BLACK color = 1 +) + +type RBTree[T Item[T]] struct { + root *redBlackNode[T] +} + +// 初始化红黒树 +func NewRBTree[T Item[T]]() *RBTree[T] { + return &RBTree[T]{} +} + +func (t *RBTree[T]) ReplaceOrInsert(item Item[T]) Item[T] { + return item +} + +func (t *RBTree[T]) Delete(item T) (T, bool) { + return *new(T), false +} + +func (t *RBTree[T]) Get(key T) (T, bool) { + return *new(T), false +} + +func (t *RBTree[T]) Has(key T) bool { + return false +} + +// 红黒树节点 +type redBlackNode[T Item[T]] struct { + Color color // 颜色 + Item T // 数据 + parent *redBlackNode[T] // 父节点 + left *redBlackNode[T] // 左 + right *redBlackNode[T] // 右 +} diff --git a/tree/tree.go b/tree/tree.go new file mode 100644 index 0000000..cf70b71 --- /dev/null +++ b/tree/tree.go @@ -0,0 +1,28 @@ +package tree + +type ITree[T Item[T]] interface { + ReplaceOrInsert(item Item[T]) Item[T] // nil cannot be added to the tree (will panic). + Delete(item T) (T, bool) // 删除节点 + Get(key T) (T, bool) // 获取节点 + Has(key T) bool // 节点在树中存在时返回true + Ascend(iterator ItemIterator[T]) // 升序 + AscendGreaterOrEqual(pivot Item[T], iterator ItemIterator[T]) // 大于等于 + AscendLessThan(pivot Item[T], iterator ItemIterator[T]) // 小于 + AscendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) // 范围迭代 + Descend(iterator ItemIterator[T]) // 降序升序迭代 + DescendGreaterThan(pivot Item[T], iterator ItemIterator[T]) // 大于,降序迭代 + DescendLessOrEquql(pivot Item[T], iterator ItemIterator[T]) // 小于等于,降序迭代 + DescendRange(greaterOrEqual, lessThan Item[T], iterator ItemIterator[T]) // 范围降序迭代 + Min() (T, bool) + Max() (T, bool) + Len() int + Clear() +} + +// 表示树中的单个对象。 +type Item[T any] interface { + Less(than T) bool +} + +// 迭代函数,返回true时停止迭代 +type ItemIterator[T Item[T]] func(i T) bool