|
- package jcstypes
-
- import (
- "github.com/samber/lo"
- "gitlink.org.cn/cloudream/common/pkgs/types"
- "gitlink.org.cn/cloudream/common/utils/math2"
- "gitlink.org.cn/cloudream/common/utils/serder"
- )
-
- type Redundancy interface {
- GetRedundancyType() string
- }
-
- var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Redundancy](
- (*NoneRedundancy)(nil),
- (*RepRedundancy)(nil),
- (*ECRedundancy)(nil),
- (*LRCRedundancy)(nil),
- (*SegmentRedundancy)(nil),
- (*MultipartUploadRedundancy)(nil),
- )), "type")
-
- type NoneRedundancy struct {
- serder.Metadata `union:"none"`
- Type string `json:"type"`
- }
-
- func (r *NoneRedundancy) GetRedundancyType() string {
- return "none"
- }
-
- func NewNoneRedundancy() *NoneRedundancy {
- return &NoneRedundancy{
- Type: "none",
- }
- }
-
- var DefaultRepRedundancy = *NewRepRedundancy(2)
-
- type RepRedundancy struct {
- serder.Metadata `union:"rep"`
- Type string `json:"type"`
- RepCount int `json:"repCount"`
- }
-
- func (r *RepRedundancy) GetRedundancyType() string {
- return "rep"
- }
-
- func NewRepRedundancy(repCount int) *RepRedundancy {
- return &RepRedundancy{
- Type: "rep",
- RepCount: repCount,
- }
- }
-
- var DefaultECRedundancy = *NewECRedundancy(2, 3, 1024*1024*5)
-
- type ECRedundancy struct {
- serder.Metadata `union:"ec"`
- Type string `json:"type"`
- K int `json:"k"`
- N int `json:"n"`
- ChunkSize int `json:"chunkSize"`
- }
-
- func (b *ECRedundancy) GetRedundancyType() string {
- return "ec"
- }
-
- func NewECRedundancy(k int, n int, chunkSize int) *ECRedundancy {
- return &ECRedundancy{
- Type: "ec",
- K: k,
- N: n,
- ChunkSize: chunkSize,
- }
- }
-
- func (b *ECRedundancy) StripSize() int64 {
- return int64(b.ChunkSize) * int64(b.K)
- }
-
- var DefaultLRCRedundancy = *NewLRCRedundancy(2, 4, []int{2}, 1024*1024*5)
-
- type LRCRedundancy struct {
- serder.Metadata `union:"lrc"`
- Type string `json:"type"`
- K int `json:"k"`
- N int `json:"n"`
- Groups []int `json:"groups"`
- ChunkSize int `json:"chunkSize"`
- }
-
- func (b *LRCRedundancy) GetRedundancyType() string {
- return "lrc"
- }
-
- func NewLRCRedundancy(k int, n int, groups []int, chunkSize int) *LRCRedundancy {
- return &LRCRedundancy{
- Type: "lrc",
- K: k,
- N: n,
- Groups: groups,
- ChunkSize: chunkSize,
- }
- }
-
- // 判断指定块属于哪个组。如果都不属于,则返回-1。
- func (b *LRCRedundancy) FindGroup(idx int) int {
- if idx >= b.N-len(b.Groups) {
- return idx - (b.N - len(b.Groups))
- }
-
- for i, group := range b.Groups {
- if idx < group {
- return i
- }
- idx -= group
- }
-
- return -1
- }
-
- // M = N - len(Groups),即数据块+校验块的总数,不包括组校验块。
- func (b *LRCRedundancy) M() int {
- return b.N - len(b.Groups)
- }
-
- func (b *LRCRedundancy) GetGroupElements(grp int) []int {
- var idxes []int
-
- grpStart := 0
- for i := 0; i < grp; i++ {
- grpStart += b.Groups[i]
- }
-
- for i := 0; i < b.Groups[grp]; i++ {
- idxes = append(idxes, grpStart+i)
- }
-
- idxes = append(idxes, b.N-len(b.Groups)+grp)
- return idxes
- }
-
- type SegmentRedundancy struct {
- serder.Metadata `union:"segment"`
- Type string `json:"type"`
- Segments []int64 `json:"segments"` // 每一段的大小
- }
-
- func (r *SegmentRedundancy) GetRedundancyType() string {
- return "segment"
- }
-
- func NewSegmentRedundancy(totalSize int64, segmentCount int) *SegmentRedundancy {
- return &SegmentRedundancy{
- Type: "segment",
- Segments: math2.SplitN(totalSize, segmentCount),
- }
- }
-
- 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
- }
-
- type MultipartUploadRedundancy struct {
- serder.Metadata `union:"multipartUpload"`
- Type string `json:"type"`
- }
-
- func (r *MultipartUploadRedundancy) GetRedundancyType() string {
- return "multipartUpload"
- }
-
- func NewMultipartUploadRedundancy() *MultipartUploadRedundancy {
- return &MultipartUploadRedundancy{
- Type: "multipartUpload",
- }
- }
|