mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-18 00:22:41 +08:00
create
This commit is contained in:
2
collections/linked_list.go
Normal file
2
collections/linked_list.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package collections
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package collections
|
package collections
|
||||||
|
|
||||||
|
// 列表
|
||||||
type List[T any] interface {
|
type List[T any] interface {
|
||||||
Add(T)
|
Add(T)
|
||||||
Delete(T)
|
Delete(T)
|
||||||
@ -7,6 +8,7 @@ type List[T any] interface {
|
|||||||
ToSlice() []T
|
ToSlice() []T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 队列
|
||||||
type Queue[T any] interface {
|
type Queue[T any] interface {
|
||||||
Put(T)
|
Put(T)
|
||||||
Poll() T
|
Poll() T
|
||||||
|
@ -40,21 +40,12 @@ func (q *ArrayQueue[T]) Poll() T {
|
|||||||
// 队列最前面元素
|
// 队列最前面元素
|
||||||
v := q.array[0]
|
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)
|
newArray := make([]T, q.size-1)
|
||||||
for i := 1; i < q.size; i++ {
|
for i := 1; i < q.size; i++ {
|
||||||
// 从老数组的第一位开始进行数据移动
|
copy(newArray, q.array[1:])
|
||||||
newArray[i-1] = q.array[i]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q.array = newArray
|
q.array = newArray
|
||||||
|
|
||||||
// 队中元素数量-1
|
// 队中元素数量-1
|
||||||
|
@ -15,6 +15,7 @@ type ArrayStack[T any] struct {
|
|||||||
lock sync.Mutex // 为了并发安全使用的锁
|
lock sync.Mutex // 为了并发安全使用的锁
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始化堆栈
|
||||||
func NewArrayStack[T any]() *ArrayStack[T] {
|
func NewArrayStack[T any]() *ArrayStack[T] {
|
||||||
return &ArrayStack[T]{}
|
return &ArrayStack[T]{}
|
||||||
}
|
}
|
||||||
|
140
errors/error_test.go
Normal file
140
errors/error_test.go
Normal file
@ -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("原生错误信息")
|
||||||
|
}
|
90
tree/bptree.go
Normal file
90
tree/bptree.go
Normal file
@ -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 {
|
||||||
|
}
|
2
tree/bptree_test.go
Normal file
2
tree/bptree_test.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package tree_test
|
||||||
|
|
112
tree/btree.go
Normal file
112
tree/btree.go
Normal file
@ -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]
|
||||||
|
}
|
15
tree/btree_test.go
Normal file
15
tree/btree_test.go
Normal file
@ -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
|
||||||
|
}
|
42
tree/rbtree.go
Normal file
42
tree/rbtree.go
Normal file
@ -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] // 右
|
||||||
|
}
|
28
tree/tree.go
Normal file
28
tree/tree.go
Normal file
@ -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
|
Reference in New Issue
Block a user