| @@ -98,7 +98,7 @@ func (s *PubShardsService) Join(ctx *gin.Context) { | |||||
| Credential: resp.PubShards.Credential, | Credential: resp.PubShards.Credential, | ||||
| ShardStore: &resp.PubShards.ShardStore, | ShardStore: &resp.PubShards.ShardStore, | ||||
| Features: resp.PubShards.Features, | Features: resp.PubShards.Features, | ||||
| WorkingDir: resp.PubShards.WorkingDir.ConcatCompsNew("parts", fmt.Sprintf("%v", s.svc.AccToken.GetToken().UserID)).String(), | |||||
| WorkingDir: resp.PubShards.WorkingDir.PushNew("parts", fmt.Sprintf("%v", s.svc.AccToken.GetToken().UserID)).String(), | |||||
| }) | }) | ||||
| if cerr2 != nil { | if cerr2 != nil { | ||||
| ctx.JSON(http.StatusOK, types.Failed(ecode.ErrorCode(cerr2.Code), cerr2.Message)) | ctx.JSON(http.StatusOK, types.Failed(ecode.ErrorCode(cerr2.Code), cerr2.Message)) | ||||
| @@ -74,7 +74,7 @@ func executeDiff(syncer *SpaceSyncer, task *task, mode *jcstypes.SpaceSyncModeDi | |||||
| } | } | ||||
| rela := e.Path.Clone() | rela := e.Path.Clone() | ||||
| rela.DropFrontN(task.Task.SrcPath.Len()) | |||||
| rela.PopFrontN(task.Task.SrcPath.Len()) | |||||
| ne := e | ne := e | ||||
| ne.Path = rela.Clone() | ne.Path = rela.Clone() | ||||
| @@ -100,7 +100,7 @@ func executeDiff(syncer *SpaceSyncer, task *task, mode *jcstypes.SpaceSyncModeDi | |||||
| } | } | ||||
| rela := e.Path.Clone() | rela := e.Path.Clone() | ||||
| rela.DropFrontN(task.Task.Dests[0].DestPath.Len()) | |||||
| rela.PopFrontN(task.Task.Dests[0].DestPath.Len()) | |||||
| ne := e | ne := e | ||||
| ne.Path = rela.Clone() | ne.Path = rela.Clone() | ||||
| @@ -154,7 +154,7 @@ func executeDiff(syncer *SpaceSyncer, task *task, mode *jcstypes.SpaceSyncModeDi | |||||
| for _, s := range syncs { | for _, s := range syncs { | ||||
| ft.AddFrom(ioswitch2.NewFromBaseStore(*srcSpace, s.Path)) | ft.AddFrom(ioswitch2.NewFromBaseStore(*srcSpace, s.Path)) | ||||
| rela := s.Path.Clone() | rela := s.Path.Clone() | ||||
| rela.DropFrontN(task.Task.SrcPath.Len()) | |||||
| rela.PopFrontN(task.Task.SrcPath.Len()) | |||||
| dstPath := task.Task.Dests[0].DestPath.ConcatNew(rela) | dstPath := task.Task.Dests[0].DestPath.ConcatNew(rela) | ||||
| to := ioswitch2.NewToBaseStore(*dstSpace, dstPath) | to := ioswitch2.NewToBaseStore(*dstSpace, dstPath) | ||||
| to.Option.ModTime = s.ModTime | to.Option.ModTime = s.ModTime | ||||
| @@ -182,7 +182,7 @@ func executeDiff(syncer *SpaceSyncer, task *task, mode *jcstypes.SpaceSyncModeDi | |||||
| if !task.Task.Options.NoEmptyDirectories && len(willMkdirs) > 0 { | if !task.Task.Options.NoEmptyDirectories && len(willMkdirs) > 0 { | ||||
| for _, p := range willMkdirs { | for _, p := range willMkdirs { | ||||
| rela := p.Clone() | rela := p.Clone() | ||||
| rela.DropFrontN(task.Task.SrcPath.Len()) | |||||
| rela.PopFrontN(task.Task.SrcPath.Len()) | |||||
| dstPath := task.Task.Dests[0].DestPath.ConcatNew(rela) | dstPath := task.Task.Dests[0].DestPath.ConcatNew(rela) | ||||
| err := dstBase.Mkdir(dstPath) | err := dstBase.Mkdir(dstPath) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -72,7 +72,7 @@ func executeFull(syncer *SpaceSyncer, task *task) { | |||||
| } | } | ||||
| rela := e.Path.Clone() | rela := e.Path.Clone() | ||||
| rela.DropFrontN(task.Task.SrcPath.Len()) | |||||
| rela.PopFrontN(task.Task.SrcPath.Len()) | |||||
| ne := e | ne := e | ||||
| ne.Path = rela.Clone() | ne.Path = rela.Clone() | ||||
| @@ -145,7 +145,7 @@ func executeFull(syncer *SpaceSyncer, task *task) { | |||||
| for i, base := range dstBases { | for i, base := range dstBases { | ||||
| if base != nil { | if base != nil { | ||||
| dirPath := task.Task.Dests[i].DestPath.Clone() | dirPath := task.Task.Dests[i].DestPath.Clone() | ||||
| dirPath.ConcatComps(path) | |||||
| dirPath.Push(path...) | |||||
| err := base.Mkdir(dirPath) | err := base.Mkdir(dirPath) | ||||
| if err != nil { | if err != nil { | ||||
| log.Warnf("mkdir %v at user space %v: %v", dirPath, dstSpaces[i].String(), err) | log.Warnf("mkdir %v at user space %v: %v", dirPath, dstSpaces[i].String(), err) | ||||
| @@ -185,10 +185,10 @@ func (u *Uploader) uploadFromBaseStore(srcSpace *jcstypes.UserSpaceDetail, targe | |||||
| } | } | ||||
| pat := e.Path.Clone() | pat := e.Path.Clone() | ||||
| pat.DropFrontN(rootPath.Len() - 1) | |||||
| pat.PopFrontN(rootPath.Len() - 1) | |||||
| // 如果对象路径和RootPath相同(即RootPath是一个文件),则用文件名作为对象Path | // 如果对象路径和RootPath相同(即RootPath是一个文件),则用文件名作为对象Path | ||||
| if pat.Len() > 1 { | if pat.Len() > 1 { | ||||
| pat.DropFrontN(1) | |||||
| pat.PopFrontN(1) | |||||
| } | } | ||||
| info := ret.Get(e.Path.String()).(*ops2.FileInfoValue) | info := ret.Get(e.Path.String()).(*ops2.FileInfoValue) | ||||
| @@ -63,7 +63,7 @@ func (s *BaseStore) Write(pat jcstypes.JPath, stream io.Reader, opt stgtypes.Wri | |||||
| } | } | ||||
| func (s *BaseStore) Read(objPath jcstypes.JPath, opt stgtypes.OpenOption) (io.ReadCloser, error) { | func (s *BaseStore) Read(objPath jcstypes.JPath, opt stgtypes.OpenOption) (io.ReadCloser, error) { | ||||
| absObjPath := filepath.Join(s.root, objPath.JoinOSPath()) | |||||
| absObjPath := filepath.Join(s.root, objPath.OSString()) | |||||
| file, err := os.Open(absObjPath) | file, err := os.Open(absObjPath) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| @@ -87,7 +87,7 @@ func (s *BaseStore) Read(objPath jcstypes.JPath, opt stgtypes.OpenOption) (io.Re | |||||
| } | } | ||||
| func (s *BaseStore) Mkdir(path jcstypes.JPath) error { | func (s *BaseStore) Mkdir(path jcstypes.JPath) error { | ||||
| absObjPath := filepath.Join(s.root, path.JoinOSPath()) | |||||
| absObjPath := filepath.Join(s.root, path.OSString()) | |||||
| err := os.MkdirAll(absObjPath, 0755) | err := os.MkdirAll(absObjPath, 0755) | ||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| @@ -98,7 +98,7 @@ func (s *BaseStore) Mkdir(path jcstypes.JPath) error { | |||||
| func (s *BaseStore) ReadDir(pat jcstypes.JPath) stgtypes.DirReader { | func (s *BaseStore) ReadDir(pat jcstypes.JPath) stgtypes.DirReader { | ||||
| return &DirReader{ | return &DirReader{ | ||||
| absRootPath: filepath.Join(s.root, pat.JoinOSPath()), | |||||
| absRootPath: filepath.Join(s.root, pat.OSString()), | |||||
| rootJPath: pat.Clone(), | rootJPath: pat.Clone(), | ||||
| } | } | ||||
| } | } | ||||
| @@ -106,7 +106,7 @@ func (s *BaseStore) ReadDir(pat jcstypes.JPath) stgtypes.DirReader { | |||||
| func (s *BaseStore) CleanTemps() { | func (s *BaseStore) CleanTemps() { | ||||
| log := s.getLogger() | log := s.getLogger() | ||||
| tempDir := filepath.Join(s.root, s.detail.UserSpace.WorkingDir.JoinOSPath(), stgtypes.TempWorkingDir) | |||||
| tempDir := filepath.Join(s.root, s.detail.UserSpace.WorkingDir.OSString(), stgtypes.TempWorkingDir) | |||||
| entries, err := os.ReadDir(tempDir) | entries, err := os.ReadDir(tempDir) | ||||
| if err != nil { | if err != nil { | ||||
| log.Warnf("read temp dir: %v", err) | log.Warnf("read temp dir: %v", err) | ||||
| @@ -57,7 +57,7 @@ func (r *DirReader) Next() (stgtypes.DirEntry, error) { | |||||
| r.curEntries = r.curEntries[1:] | r.curEntries = r.curEntries[1:] | ||||
| if entry.entry.IsDir() { | if entry.entry.IsDir() { | ||||
| es, err := os.ReadDir(filepath.Join(r.absRootPath, entry.dir.JoinOSPath(), entry.entry.Name())) | |||||
| es, err := os.ReadDir(filepath.Join(r.absRootPath, entry.dir.OSString(), entry.entry.Name())) | |||||
| if err != nil { | if err != nil { | ||||
| return stgtypes.DirEntry{}, err | return stgtypes.DirEntry{}, err | ||||
| } | } | ||||
| @@ -31,7 +31,7 @@ func (*Multiparter) MaxPartSize() int64 { | |||||
| } | } | ||||
| func (m *Multiparter) Initiate(ctx context.Context) (stgtypes.MultipartTask, error) { | func (m *Multiparter) Initiate(ctx context.Context) (stgtypes.MultipartTask, error) { | ||||
| tempDir := filepath.Join(m.localStg.RootDir, m.detail.UserSpace.WorkingDir.JoinOSPath(), stgtypes.TempWorkingDir) | |||||
| tempDir := filepath.Join(m.localStg.RootDir, m.detail.UserSpace.WorkingDir.OSString(), stgtypes.TempWorkingDir) | |||||
| absTempDir, err := filepath.Abs(tempDir) | absTempDir, err := filepath.Abs(tempDir) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("get abs temp dir %v: %v", tempDir, err) | return nil, fmt.Errorf("get abs temp dir %v: %v", tempDir, err) | ||||
| @@ -51,7 +51,7 @@ func (m *Multiparter) Initiate(ctx context.Context) (stgtypes.MultipartTask, err | |||||
| absTempDir: absTempDir, | absTempDir: absTempDir, | ||||
| tempFileName: tempFileName, | tempFileName: tempFileName, | ||||
| tempPartsDir: tempPartsDir, | tempPartsDir: tempPartsDir, | ||||
| joinedFileJPath: m.detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.TempWorkingDir, tempFileName+".joined"), | |||||
| joinedFileJPath: m.detail.UserSpace.WorkingDir.PushNew(stgtypes.TempWorkingDir, tempFileName+".joined"), | |||||
| absJoinedFilePath: absJoinedFilePath, | absJoinedFilePath: absJoinedFilePath, | ||||
| uploadID: tempPartsDir, | uploadID: tempPartsDir, | ||||
| }, nil | }, nil | ||||
| @@ -39,13 +39,13 @@ func (*S2STransfer) CanTransfer(src, dst *jcstypes.UserSpaceDetail) bool { | |||||
| func (s *S2STransfer) Transfer(ctx context.Context, src *jcstypes.UserSpaceDetail, srcPath jcstypes.JPath, dstPath jcstypes.JPath) (stgtypes.FileInfo, error) { | func (s *S2STransfer) Transfer(ctx context.Context, src *jcstypes.UserSpaceDetail, srcPath jcstypes.JPath, dstPath jcstypes.JPath) (stgtypes.FileInfo, error) { | ||||
| s.dstPath = dstPath | s.dstPath = dstPath | ||||
| copy, err := os.OpenFile(filepath.Join(s.localStg.RootDir, s.dstPath.JoinOSPath()), os.O_WRONLY|os.O_CREATE, 0644) | |||||
| copy, err := os.OpenFile(filepath.Join(s.localStg.RootDir, s.dstPath.OSString()), os.O_WRONLY|os.O_CREATE, 0644) | |||||
| if err != nil { | if err != nil { | ||||
| return stgtypes.FileInfo{}, err | return stgtypes.FileInfo{}, err | ||||
| } | } | ||||
| defer copy.Close() | defer copy.Close() | ||||
| srcFile, err := os.Open(filepath.Join(s.localStg.RootDir, srcPath.JoinOSPath())) | |||||
| srcFile, err := os.Open(filepath.Join(s.localStg.RootDir, srcPath.OSString())) | |||||
| if err != nil { | if err != nil { | ||||
| return stgtypes.FileInfo{}, err | return stgtypes.FileInfo{}, err | ||||
| } | } | ||||
| @@ -22,7 +22,7 @@ type ShardStore struct { | |||||
| } | } | ||||
| func NewShardStore(root string, detail *jcstypes.UserSpaceDetail) (*ShardStore, error) { | func NewShardStore(root string, detail *jcstypes.UserSpaceDetail) (*ShardStore, error) { | ||||
| storeAbsRoot, err := filepath.Abs(filepath.Join(root, detail.UserSpace.WorkingDir.JoinOSPath(), stgtypes.ShardStoreWorkingDir)) | |||||
| storeAbsRoot, err := filepath.Abs(filepath.Join(root, detail.UserSpace.WorkingDir.OSString(), stgtypes.ShardStoreWorkingDir)) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("get abs root: %w", err) | return nil, fmt.Errorf("get abs root: %w", err) | ||||
| } | } | ||||
| @@ -44,7 +44,7 @@ func (s *ShardStore) Stop() { | |||||
| } | } | ||||
| func (s *ShardStore) Store(path jcstypes.JPath, hash jcstypes.FileHash, size int64) (stgtypes.FileInfo, error) { | func (s *ShardStore) Store(path jcstypes.JPath, hash jcstypes.FileHash, size int64) (stgtypes.FileInfo, error) { | ||||
| fullTempPath := filepath.Join(s.stgRoot, path.JoinOSPath()) | |||||
| fullTempPath := filepath.Join(s.stgRoot, path.OSString()) | |||||
| s.lock.Lock() | s.lock.Lock() | ||||
| defer s.lock.Unlock() | defer s.lock.Unlock() | ||||
| @@ -208,5 +208,5 @@ func (s *ShardStore) getFilePathFromHash(hash jcstypes.FileHash) string { | |||||
| } | } | ||||
| func (s *ShardStore) getJPathFromHash(hash jcstypes.FileHash) jcstypes.JPath { | func (s *ShardStore) getJPathFromHash(hash jcstypes.FileHash) jcstypes.JPath { | ||||
| return s.detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)) | |||||
| return s.detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)) | |||||
| } | } | ||||
| @@ -250,21 +250,21 @@ func (s *ShardStore) getLogger() logger.Logger { | |||||
| } | } | ||||
| func (s *ShardStore) getFileDirFromHash(hash jcstypes.FileHash) string { | func (s *ShardStore) getFileDirFromHash(hash jcstypes.FileHash) string { | ||||
| return s.Detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2)).String() | |||||
| return s.Detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2)).String() | |||||
| } | } | ||||
| func (s *ShardStore) getFilePathFromHash(hash jcstypes.FileHash) string { | func (s *ShardStore) getFilePathFromHash(hash jcstypes.FileHash) string { | ||||
| return s.Detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)).String() | |||||
| return s.Detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)).String() | |||||
| } | } | ||||
| func (s *ShardStore) getJPathFromHash(hash jcstypes.FileHash) jcstypes.JPath { | func (s *ShardStore) getJPathFromHash(hash jcstypes.FileHash) jcstypes.JPath { | ||||
| return s.Detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)) | |||||
| return s.Detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir, hash.GetHashPrefix(2), string(hash)) | |||||
| } | } | ||||
| func (s *ShardStore) getStoreRoot() string { | func (s *ShardStore) getStoreRoot() string { | ||||
| return s.Detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir).String() | |||||
| return s.Detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir).String() | |||||
| } | } | ||||
| func (s *ShardStore) getStoreRootJPath() jcstypes.JPath { | func (s *ShardStore) getStoreRootJPath() jcstypes.JPath { | ||||
| return s.Detail.UserSpace.WorkingDir.ConcatCompsNew(stgtypes.ShardStoreWorkingDir) | |||||
| return s.Detail.UserSpace.WorkingDir.PushNew(stgtypes.ShardStoreWorkingDir) | |||||
| } | } | ||||
| @@ -19,6 +19,6 @@ func FindFeature[T jcstypes.StorageFeature](detail *jcstypes.UserSpaceDetail) T | |||||
| func MakeTempDirPath(detail *jcstypes.UserSpaceDetail, comps ...string) jcstypes.JPath { | func MakeTempDirPath(detail *jcstypes.UserSpaceDetail, comps ...string) jcstypes.JPath { | ||||
| p := detail.UserSpace.WorkingDir.Clone() | p := detail.UserSpace.WorkingDir.Clone() | ||||
| p.Push(TempWorkingDir) | p.Push(TempWorkingDir) | ||||
| p.ConcatComps(comps) | |||||
| p.Push(comps...) | |||||
| return p | return p | ||||
| } | } | ||||
| @@ -31,8 +31,14 @@ func (p *JPath) LastComp() string { | |||||
| return p.comps[len(p.comps)-1] | return p.comps[len(p.comps)-1] | ||||
| } | } | ||||
| func (p *JPath) Push(comp string) { | |||||
| p.comps = append(p.comps, comp) | |||||
| func (p *JPath) Push(comp ...string) { | |||||
| p.comps = append(p.comps, comp...) | |||||
| } | |||||
| func (p *JPath) PushNew(comp ...string) JPath { | |||||
| clone := p.Clone() | |||||
| clone.Push(comp...) | |||||
| return clone | |||||
| } | } | ||||
| func (p *JPath) Pop() string { | func (p *JPath) Pop() string { | ||||
| @@ -44,7 +50,19 @@ func (p *JPath) Pop() string { | |||||
| return comp | return comp | ||||
| } | } | ||||
| func (p *JPath) SplitParent() JPath { | |||||
| func (p *JPath) PopFrontN(cnt int) { | |||||
| if cnt >= len(p.comps) { | |||||
| p.comps = nil | |||||
| return | |||||
| } | |||||
| if cnt <= 0 { | |||||
| return | |||||
| } | |||||
| p.comps = p.comps[cnt:] | |||||
| } | |||||
| func (p *JPath) CutParent() JPath { | |||||
| if len(p.comps) <= 1 { | if len(p.comps) <= 1 { | ||||
| return JPath{} | return JPath{} | ||||
| } | } | ||||
| @@ -69,18 +87,6 @@ func (p *JPath) CopyParent() JPath { | |||||
| return parent | return parent | ||||
| } | } | ||||
| func (p *JPath) DropFrontN(cnt int) { | |||||
| if cnt >= len(p.comps) { | |||||
| p.comps = nil | |||||
| return | |||||
| } | |||||
| if cnt <= 0 { | |||||
| return | |||||
| } | |||||
| p.comps = p.comps[cnt:] | |||||
| } | |||||
| func (p *JPath) Concat(other JPath) { | func (p *JPath) Concat(other JPath) { | ||||
| p.comps = append(p.comps, other.comps...) | p.comps = append(p.comps, other.comps...) | ||||
| } | } | ||||
| @@ -91,16 +97,6 @@ func (p *JPath) ConcatNew(other JPath) JPath { | |||||
| return clone | return clone | ||||
| } | } | ||||
| func (p *JPath) ConcatComps(comps []string) { | |||||
| p.comps = append(p.comps, comps...) | |||||
| } | |||||
| func (p *JPath) ConcatCompsNew(comps ...string) JPath { | |||||
| clone := p.Clone() | |||||
| clone.ConcatComps(comps) | |||||
| return clone | |||||
| } | |||||
| func (p *JPath) Clone() JPath { | func (p *JPath) Clone() JPath { | ||||
| clone := JPath{ | clone := JPath{ | ||||
| comps: make([]string, len(p.comps)), | comps: make([]string, len(p.comps)), | ||||
| @@ -109,7 +105,7 @@ func (p *JPath) Clone() JPath { | |||||
| return clone | return clone | ||||
| } | } | ||||
| func (p *JPath) JoinOSPath() string { | |||||
| func (p *JPath) OSString() string { | |||||
| return filepath.Join(p.comps...) | return filepath.Join(p.comps...) | ||||
| } | } | ||||
| @@ -48,7 +48,7 @@ func (i *FileIterator) MoveNext() (*cliapi.UploadingObject, error) { | |||||
| i.curEntries = i.curEntries[1:] | i.curEntries = i.curEntries[1:] | ||||
| if entry.entry.IsDir() { | if entry.entry.IsDir() { | ||||
| es, err := os.ReadDir(filepath.Join(i.absRootPath, entry.dir.JoinOSPath(), entry.entry.Name())) | |||||
| es, err := os.ReadDir(filepath.Join(i.absRootPath, entry.dir.OSString(), entry.entry.Name())) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -65,7 +65,7 @@ func (i *FileIterator) MoveNext() (*cliapi.UploadingObject, error) { | |||||
| continue | continue | ||||
| } | } | ||||
| file, err := os.Open(filepath.Join(i.absRootPath, entry.dir.JoinOSPath(), entry.entry.Name())) | |||||
| file, err := os.Open(filepath.Join(i.absRootPath, entry.dir.OSString(), entry.entry.Name())) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -78,7 +78,7 @@ func (i *FileIterator) MoveNext() (*cliapi.UploadingObject, error) { | |||||
| i.fileCount++ | i.fileCount++ | ||||
| jpath := i.jpathRoot.ConcatNew(entry.dir) | jpath := i.jpathRoot.ConcatNew(entry.dir) | ||||
| path := jpath.ConcatCompsNew(entry.entry.Name()).String() | |||||
| path := jpath.PushNew(entry.entry.Name()).String() | |||||
| now := time.Now() | now := time.Now() | ||||
| if !i.lastStartTime.IsZero() { | if !i.lastStartTime.IsZero() { | ||||