| @@ -83,6 +83,14 @@ func Init(cfg *Config) error { | |||||
| // 下面是日志记录的方法,它们分别对应不同的日志级别和格式。 | // 下面是日志记录的方法,它们分别对应不同的日志级别和格式。 | ||||
| // 这些方法最终都会调用logrus对应的方法来记录日志。 | // 这些方法最终都会调用logrus对应的方法来记录日志。 | ||||
| func Trace(args ...interface{}) { | |||||
| logrus.Trace(args...) | |||||
| } | |||||
| func Tracef(format string, args ...interface{}) { | |||||
| logrus.Tracef(format, args...) | |||||
| } | |||||
| func Debug(args ...interface{}) { | func Debug(args ...interface{}) { | ||||
| logrus.Debug(args...) | logrus.Debug(args...) | ||||
| } | } | ||||
| @@ -102,10 +102,15 @@ func (n *Node[T]) RemoveSelf(cleanParent bool) { | |||||
| } | } | ||||
| // 修改时需要注意允许在visitorFn中删除当前节点 | // 修改时需要注意允许在visitorFn中删除当前节点 | ||||
| func (n *Node[T]) Iterate(visitorFn func(word string, node *Node[T], isWordNode bool) VisitCtrl) { | |||||
| func (n *Node[T]) Iterate(visitorFn func(path []string, node *Node[T], isWordNode bool) VisitCtrl) { | |||||
| n.iterate([]string{}, visitorFn) | |||||
| } | |||||
| func (n *Node[T]) iterate(path []string, visitorFn func(path []string, node *Node[T], isWordNode bool) VisitCtrl) { | |||||
| if n.WordNexts != nil { | if n.WordNexts != nil { | ||||
| for word, node := range n.WordNexts { | for word, node := range n.WordNexts { | ||||
| ret := visitorFn(word, node, true) | |||||
| newPath := append(path, word) | |||||
| ret := visitorFn(newPath, node, true) | |||||
| if ret == VisitBreak { | if ret == VisitBreak { | ||||
| return | return | ||||
| } | } | ||||
| @@ -114,12 +119,13 @@ func (n *Node[T]) Iterate(visitorFn func(word string, node *Node[T], isWordNode | |||||
| continue | continue | ||||
| } | } | ||||
| node.Iterate(visitorFn) | |||||
| node.iterate(newPath, visitorFn) | |||||
| } | } | ||||
| } | } | ||||
| if n.AnyNext != nil { | if n.AnyNext != nil { | ||||
| ret := visitorFn("", n.AnyNext, false) | |||||
| newPath := append(path, "") | |||||
| ret := visitorFn(newPath, n.AnyNext, false) | |||||
| if ret == VisitBreak { | if ret == VisitBreak { | ||||
| return | return | ||||
| } | } | ||||
| @@ -128,7 +134,7 @@ func (n *Node[T]) Iterate(visitorFn func(word string, node *Node[T], isWordNode | |||||
| return | return | ||||
| } | } | ||||
| n.AnyNext.Iterate(visitorFn) | |||||
| n.AnyNext.iterate(newPath, visitorFn) | |||||
| } | } | ||||
| } | } | ||||
| @@ -198,6 +204,6 @@ func (t *Trie[T]) CreateWords(words []string) *Node[T] { | |||||
| return ptr | return ptr | ||||
| } | } | ||||
| func (n *Trie[T]) Iterate(visitorFn func(word string, node *Node[T], isWordNode bool) VisitCtrl) { | |||||
| func (n *Trie[T]) Iterate(visitorFn func(path []string, node *Node[T], isWordNode bool) VisitCtrl) { | |||||
| n.Root.Iterate(visitorFn) | n.Root.Iterate(visitorFn) | ||||
| } | } | ||||
| @@ -257,10 +257,11 @@ const ( | |||||
| ) | ) | ||||
| type Package struct { | type Package struct { | ||||
| PackageID PackageID `gorm:"column:PackageID; primaryKey; type:bigint; autoIncrement" json:"packageID"` | |||||
| Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` | |||||
| BucketID BucketID `gorm:"column:BucketID; type:bigint; not null" json:"bucketID"` | |||||
| State string `gorm:"column:State; type:varchar(255); not null" json:"state"` | |||||
| PackageID PackageID `gorm:"column:PackageID; primaryKey; type:bigint; autoIncrement" json:"packageID"` | |||||
| Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` | |||||
| BucketID BucketID `gorm:"column:BucketID; type:bigint; not null" json:"bucketID"` | |||||
| CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"` | |||||
| State string `gorm:"column:State; type:varchar(255); not null" json:"state"` | |||||
| } | } | ||||
| func (Package) TableName() string { | func (Package) TableName() string { | ||||
| @@ -337,9 +338,10 @@ func (PinnedObject) TableName() string { | |||||
| } | } | ||||
| type Bucket struct { | type Bucket struct { | ||||
| BucketID BucketID `gorm:"column:BucketID; primaryKey; type:bigint; autoIncrement" json:"bucketID"` | |||||
| Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` | |||||
| CreatorID UserID `gorm:"column:CreatorID; type:bigint; not null" json:"creatorID"` | |||||
| BucketID BucketID `gorm:"column:BucketID; primaryKey; type:bigint; autoIncrement" json:"bucketID"` | |||||
| Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` | |||||
| CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"` | |||||
| CreatorID UserID `gorm:"column:CreatorID; type:bigint; not null" json:"creatorID"` | |||||
| } | } | ||||
| func (Bucket) TableName() string { | func (Bucket) TableName() string { | ||||
| @@ -11,3 +11,8 @@ func JoinObjectPath(comps ...string) string { | |||||
| func SplitObjectPath(pat string) []string { | func SplitObjectPath(pat string) []string { | ||||
| return strings.Split(pat, ObjectPathSeparator) | return strings.Split(pat, ObjectPathSeparator) | ||||
| } | } | ||||
| func BaseName(pat string) string { | |||||
| idx := strings.LastIndex(pat, ObjectPathSeparator) | |||||
| return pat[idx+1:] | |||||
| } | |||||
| @@ -73,3 +73,24 @@ func Deref[T any](arr []*T) []T { | |||||
| return result | return result | ||||
| } | } | ||||
| func AppendNew[T any](arr []T, items ...T) []T { | |||||
| narr := make([]T, 0, len(arr)+len(items)) | |||||
| narr = append(narr, arr...) | |||||
| narr = append(narr, items...) | |||||
| return narr | |||||
| } | |||||
| func ArrayEquals[T comparable](arr1, arr2 []T) bool { | |||||
| if len(arr1) != len(arr2) { | |||||
| return false | |||||
| } | |||||
| for i := 0; i < len(arr1); i++ { | |||||
| if arr1[i] != arr2[i] { | |||||
| return false | |||||
| } | |||||
| } | |||||
| return true | |||||
| } | |||||
| @@ -2,6 +2,18 @@ package math2 | |||||
| import "golang.org/x/exp/constraints" | import "golang.org/x/exp/constraints" | ||||
| func Sign[T constraints.Signed](v T) int { | |||||
| if v > 0 { | |||||
| return 1 | |||||
| } | |||||
| if v < 0 { | |||||
| return -1 | |||||
| } | |||||
| return 0 | |||||
| } | |||||
| func Max[T constraints.Ordered](v1, v2 T) T { | func Max[T constraints.Ordered](v1, v2 T) T { | ||||
| if v1 < v2 { | if v1 < v2 { | ||||
| return v2 | return v2 | ||||