| @@ -15,6 +15,7 @@ var Global = struct { | |||||
| OS string | OS string | ||||
| Arch string | Arch string | ||||
| BuildRoot string | BuildRoot string | ||||
| Debug bool | |||||
| }{ | }{ | ||||
| Arch: "amd64", | Arch: "amd64", | ||||
| } | } | ||||
| @@ -50,7 +51,14 @@ func Build(args BuildArgs) error { | |||||
| binPath := filepath.Join(fullOutputDir, args.OutputName+goBuildArgs.OutputExt) | binPath := filepath.Join(fullOutputDir, args.OutputName+goBuildArgs.OutputExt) | ||||
| fmt.Printf("building to %s\n", binPath) | fmt.Printf("building to %s\n", binPath) | ||||
| goCmdArgs := []string{"build", "-o", binPath} | |||||
| goCmdArgs := []string{"build"} | |||||
| if Global.Debug { | |||||
| goCmdArgs = append(goCmdArgs, "-gcflags", "all=-N -l") | |||||
| } | |||||
| goCmdArgs = append(goCmdArgs, "-o", binPath) | |||||
| if args.EntryFile != "" { | if args.EntryFile != "" { | ||||
| goCmdArgs = append(goCmdArgs, args.EntryFile) | goCmdArgs = append(goCmdArgs, args.EntryFile) | ||||
| } | } | ||||
| @@ -28,3 +28,8 @@ func ARM64() { | |||||
| func BuildRoot(dir string) { | func BuildRoot(dir string) { | ||||
| magefiles.Global.BuildRoot = dir | magefiles.Global.BuildRoot = dir | ||||
| } | } | ||||
| // [配置项]关闭编译优化,用于调试 | |||||
| func Debug() { | |||||
| magefiles.Global.Debug = true | |||||
| } | |||||
| @@ -114,6 +114,31 @@ func (s *InputSlots) EnlargeOne() int { | |||||
| return s.Len() - 1 | return s.Len() - 1 | ||||
| } | } | ||||
| func (s *InputSlots) GetVarIDs() []exec.VarID { | |||||
| var ids []exec.VarID | |||||
| for _, v := range s.RawArray() { | |||||
| if v == nil { | |||||
| continue | |||||
| } | |||||
| ids = append(ids, v.VarID) | |||||
| } | |||||
| return ids | |||||
| } | |||||
| func (s *InputSlots) GetVarIDsRanged(start, end int) []exec.VarID { | |||||
| var ids []exec.VarID | |||||
| for i := start; i < end; i++ { | |||||
| v := s.Get(i) | |||||
| if v == nil { | |||||
| continue | |||||
| } | |||||
| ids = append(ids, v.VarID) | |||||
| } | |||||
| return ids | |||||
| } | |||||
| type OutputSlots struct { | type OutputSlots struct { | ||||
| VarSlots | VarSlots | ||||
| } | } | ||||
| @@ -138,6 +163,31 @@ func (s *OutputSlots) SetupNew(my Node, v *Var) { | |||||
| } | } | ||||
| } | } | ||||
| func (s *OutputSlots) GetVarIDs() []exec.VarID { | |||||
| var ids []exec.VarID | |||||
| for _, v := range s.RawArray() { | |||||
| if v == nil { | |||||
| continue | |||||
| } | |||||
| ids = append(ids, v.VarID) | |||||
| } | |||||
| return ids | |||||
| } | |||||
| func (s *OutputSlots) GetVarIDsRanged(start, end int) []exec.VarID { | |||||
| var ids []exec.VarID | |||||
| for i := start; i < end; i++ { | |||||
| v := s.Get(i) | |||||
| if v == nil { | |||||
| continue | |||||
| } | |||||
| ids = append(ids, v.VarID) | |||||
| } | |||||
| return ids | |||||
| } | |||||
| type Slot struct { | type Slot struct { | ||||
| Var *Var | Var *Var | ||||
| Index int | Index int | ||||
| @@ -14,6 +14,10 @@ type Range struct { | |||||
| Length *int64 | Length *int64 | ||||
| } | } | ||||
| func NewRange(offset int64, length int64) Range { | |||||
| return Range{Offset: offset, Length: &length} | |||||
| } | |||||
| func (r *Range) Extend(other Range) { | func (r *Range) Extend(other Range) { | ||||
| newOffset := math2.Min(r.Offset, other.Offset) | newOffset := math2.Min(r.Offset, other.Offset) | ||||
| @@ -119,6 +119,9 @@ func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error { | |||||
| graph.Walk(func(node dag.Node) bool { | graph.Walk(func(node dag.Node) bool { | ||||
| for i := 0; i < node.OutputStreams().Len(); i++ { | for i := 0; i < node.OutputStreams().Len(); i++ { | ||||
| out := node.OutputStreams().Get(i) | out := node.OutputStreams().Get(i) | ||||
| if out == nil { | |||||
| continue | |||||
| } | |||||
| if out.VarID > 0 { | if out.VarID > 0 { | ||||
| continue | continue | ||||
| @@ -129,6 +132,9 @@ func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error { | |||||
| for i := 0; i < node.InputStreams().Len(); i++ { | for i := 0; i < node.InputStreams().Len(); i++ { | ||||
| in := node.InputStreams().Get(i) | in := node.InputStreams().Get(i) | ||||
| if in == nil { | |||||
| continue | |||||
| } | |||||
| if in.VarID > 0 { | if in.VarID > 0 { | ||||
| continue | continue | ||||
| @@ -139,6 +145,9 @@ func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error { | |||||
| for i := 0; i < node.OutputValues().Len(); i++ { | for i := 0; i < node.OutputValues().Len(); i++ { | ||||
| out := node.OutputValues().Get(i) | out := node.OutputValues().Get(i) | ||||
| if out == nil { | |||||
| continue | |||||
| } | |||||
| if out.VarID > 0 { | if out.VarID > 0 { | ||||
| continue | continue | ||||
| @@ -149,6 +158,9 @@ func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error { | |||||
| for i := 0; i < node.InputValues().Len(); i++ { | for i := 0; i < node.InputValues().Len(); i++ { | ||||
| in := node.InputValues().Get(i) | in := node.InputValues().Get(i) | ||||
| if in == nil { | |||||
| continue | |||||
| } | |||||
| if in.VarID > 0 { | if in.VarID > 0 { | ||||
| continue | continue | ||||
| @@ -5,6 +5,7 @@ import ( | |||||
| "fmt" | "fmt" | ||||
| "time" | "time" | ||||
| "github.com/samber/lo" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/types" | "gitlink.org.cn/cloudream/common/pkgs/types" | ||||
| "gitlink.org.cn/cloudream/common/utils/serder" | "gitlink.org.cn/cloudream/common/utils/serder" | ||||
| ) | ) | ||||
| @@ -33,7 +34,6 @@ type FileHash string | |||||
| /// TODO 将分散在各处的公共结构体定义集中到这里来 | /// TODO 将分散在各处的公共结构体定义集中到这里来 | ||||
| type Redundancy interface { | type Redundancy interface { | ||||
| driver.Valuer | |||||
| } | } | ||||
| var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Redundancy]( | var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Redundancy]( | ||||
| @@ -41,6 +41,7 @@ var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTyp | |||||
| (*RepRedundancy)(nil), | (*RepRedundancy)(nil), | ||||
| (*ECRedundancy)(nil), | (*ECRedundancy)(nil), | ||||
| (*LRCRedundancy)(nil), | (*LRCRedundancy)(nil), | ||||
| (*SegmentRedundancy)(nil), | |||||
| )), "type") | )), "type") | ||||
| type NoneRedundancy struct { | type NoneRedundancy struct { | ||||
| @@ -162,6 +163,83 @@ func (b *LRCRedundancy) GetGroupElements(grp int) []int { | |||||
| return idxes | return idxes | ||||
| } | } | ||||
| type SegmentRedundancy struct { | |||||
| serder.Metadata `union:"segment"` | |||||
| Type string `json:"type"` | |||||
| Segments []int64 `json:"segments"` // 每一段的大小 | |||||
| } | |||||
| func NewSegmentRedundancy(totalSize int64, segmentCount int) *SegmentRedundancy { | |||||
| var segs []int64 | |||||
| segLen := int64(0) | |||||
| // 计算每一段的大小。大小不一定都相同,但总和应该等于总大小。 | |||||
| for i := 0; i < segmentCount; i++ { | |||||
| curLen := totalSize*int64(i+1)/int64(segmentCount) - segLen | |||||
| segs = append(segs, curLen) | |||||
| segLen += curLen | |||||
| } | |||||
| return &SegmentRedundancy{ | |||||
| Type: "segment", | |||||
| Segments: segs, | |||||
| } | |||||
| } | |||||
| func (r *SegmentRedundancy) SegmentCount() int { | |||||
| return len(r.Segments) | |||||
| } | |||||
| func (r *SegmentRedundancy) CalcSegmentStart(index int) int64 { | |||||
| return lo.Sum(r.Segments[:index]) | |||||
| } | |||||
| // 计算指定位置取整到最近的段的起始位置。 | |||||
| func (r *SegmentRedundancy) FloorSegmentPosition(pos int64) int64 { | |||||
| fpos := int64(0) | |||||
| for _, segLen := range r.Segments { | |||||
| segEnd := fpos + segLen | |||||
| if pos < segEnd { | |||||
| break | |||||
| } | |||||
| fpos += segLen | |||||
| } | |||||
| return fpos | |||||
| } | |||||
| // 计算指定范围内的段索引范围,参数和返回值所代表的范围都是左闭右开的。 | |||||
| // 如果end == -1,则代表计算从start到最后一个字节的范围。 | |||||
| func (b *SegmentRedundancy) CalcSegmentRange(start int64, end *int64) (segIdxStart int, segIdxEnd int) { | |||||
| segIdxStart = len(b.Segments) | |||||
| segIdxEnd = len(b.Segments) | |||||
| // 找到第一个包含start的段索引 | |||||
| segStart := int64(0) | |||||
| for i, segLen := range b.Segments { | |||||
| segEnd := segStart + segLen | |||||
| if start < segEnd { | |||||
| segIdxStart = i | |||||
| break | |||||
| } | |||||
| segStart += segLen | |||||
| } | |||||
| if end != nil { | |||||
| // 找到第一个包含end的段索引 | |||||
| segStart = int64(0) | |||||
| for i, segLen := range b.Segments { | |||||
| segEnd := segStart + segLen | |||||
| if *end <= segEnd { | |||||
| segIdxEnd = i + 1 | |||||
| break | |||||
| } | |||||
| segStart += segLen | |||||
| } | |||||
| } | |||||
| return | |||||
| } | |||||
| const ( | const ( | ||||
| PackageStateNormal = "Normal" | PackageStateNormal = "Normal" | ||||
| PackageStateDeleted = "Deleted" | PackageStateDeleted = "Deleted" | ||||
| @@ -1,6 +1,9 @@ | |||||
| package lo2 | package lo2 | ||||
| import "github.com/samber/lo" | |||||
| import ( | |||||
| "github.com/samber/lo" | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | |||||
| ) | |||||
| func Remove[T comparable](arr []T, item T) []T { | func Remove[T comparable](arr []T, item T) []T { | ||||
| index := lo.IndexOf(arr, item) | index := lo.IndexOf(arr, item) | ||||
| @@ -25,6 +28,16 @@ func RemoveAt[T any](arr []T, index int) []T { | |||||
| return append(arr[:index], arr[index+1:]...) | return append(arr[:index], arr[index+1:]...) | ||||
| } | } | ||||
| func RemoveRange[T any](arr []T, start int, length int) []T { | |||||
| if start >= len(arr) { | |||||
| return arr | |||||
| } | |||||
| length = math2.Min(len(arr), start+length) - start | |||||
| copy(arr[start:], arr[start+length:]) | |||||
| return arr[:len(arr)-length] | |||||
| } | |||||
| func RemoveAllDefault[T comparable](arr []T) []T { | func RemoveAllDefault[T comparable](arr []T) []T { | ||||
| var def T | var def T | ||||
| return lo.Filter(arr, func(i T, idx int) bool { | return lo.Filter(arr, func(i T, idx int) bool { | ||||
| @@ -33,3 +33,15 @@ func CeilDiv[T constraints.Integer](v T, div T) T { | |||||
| func FloorDiv[T constraints.Integer](v T, div T) T { | func FloorDiv[T constraints.Integer](v T, div T) T { | ||||
| return v / div | return v / div | ||||
| } | } | ||||
| func Clamp[T constraints.Integer](v, min, max T) T { | |||||
| if v < min { | |||||
| return min | |||||
| } | |||||
| if v > max { | |||||
| return max | |||||
| } | |||||
| return v | |||||
| } | |||||