| @@ -22,7 +22,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder" | "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ec" | "gitlink.org.cn/cloudream/storage/common/pkgs/ec" | ||||
| coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/utils" | "gitlink.org.cn/cloudream/storage/common/utils" | ||||
| ) | ) | ||||
| @@ -11,7 +11,7 @@ import ( | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| func init() { | func init() { | ||||
| @@ -12,7 +12,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | "gitlink.org.cn/cloudream/common/utils/math2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| type DefaultParser struct { | type DefaultParser struct { | ||||
| @@ -11,7 +11,7 @@ import ( | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| func init() { | func init() { | ||||
| @@ -10,7 +10,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | "gitlink.org.cn/cloudream/common/utils/math2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc/ops2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc/ops2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| // 计算输入流的打开范围。会把流的范围按条带大小取整 | // 计算输入流的打开范围。会把流的范围按条带大小取整 | ||||
| @@ -11,9 +11,8 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/storages/utils" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| stypes "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/utils" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -21,35 +20,35 @@ const ( | |||||
| BlocksDir = "blocks" | BlocksDir = "blocks" | ||||
| ) | ) | ||||
| type Local struct { | |||||
| type ShardStore struct { | |||||
| cfg cdssdk.LocalShardStorage | cfg cdssdk.LocalShardStorage | ||||
| } | } | ||||
| func New(stg cdssdk.Storage, cfg cdssdk.LocalShardStorage) (*Local, error) { | |||||
| func NewShardStore(stg cdssdk.Storage, cfg cdssdk.LocalShardStorage) (*ShardStore, error) { | |||||
| _, ok := stg.Address.(*cdssdk.LocalStorageAddress) | _, ok := stg.Address.(*cdssdk.LocalStorageAddress) | ||||
| if !ok { | if !ok { | ||||
| return nil, fmt.Errorf("storage address(%T) is not local", stg) | return nil, fmt.Errorf("storage address(%T) is not local", stg) | ||||
| } | } | ||||
| return &Local{ | |||||
| return &ShardStore{ | |||||
| cfg: cfg, | cfg: cfg, | ||||
| }, nil | }, nil | ||||
| } | } | ||||
| func (s *Local) Start(ch *stypes.StorageEventChan) { | |||||
| func (s *ShardStore) Start(ch *types.StorageEventChan) { | |||||
| } | } | ||||
| func (s *Local) Stop() { | |||||
| func (s *ShardStore) Stop() { | |||||
| } | } | ||||
| func (s *Local) New() types.Writer { | |||||
| func (s *ShardStore) New() types.ShardWriter { | |||||
| file, err := os.CreateTemp(filepath.Join(s.cfg.Root, "tmp"), "tmp-*") | file, err := os.CreateTemp(filepath.Join(s.cfg.Root, "tmp"), "tmp-*") | ||||
| if err != nil { | if err != nil { | ||||
| return utils.ErrorWriter(err) | |||||
| return utils.ErrorShardWriter(err) | |||||
| } | } | ||||
| return &Writer{ | |||||
| return &ShardWriter{ | |||||
| path: filepath.Join(s.cfg.Root, "tmp", file.Name()), | path: filepath.Join(s.cfg.Root, "tmp", file.Name()), | ||||
| file: file, | file: file, | ||||
| hasher: sha256.New(), | hasher: sha256.New(), | ||||
| @@ -58,7 +57,7 @@ func (s *Local) New() types.Writer { | |||||
| } | } | ||||
| // 使用F函数创建Option对象 | // 使用F函数创建Option对象 | ||||
| func (s *Local) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| func (s *ShardStore) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| fileName := string(opt.FileHash) | fileName := string(opt.FileHash) | ||||
| if len(fileName) < 2 { | if len(fileName) < 2 { | ||||
| return nil, fmt.Errorf("invalid file name") | return nil, fmt.Errorf("invalid file name") | ||||
| @@ -85,7 +84,7 @@ func (s *Local) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| return file, nil | return file, nil | ||||
| } | } | ||||
| func (s *Local) ListAll() ([]types.FileInfo, error) { | |||||
| func (s *ShardStore) ListAll() ([]types.FileInfo, error) { | |||||
| var infos []types.FileInfo | var infos []types.FileInfo | ||||
| blockDir := filepath.Join(s.cfg.Root, BlocksDir) | blockDir := filepath.Join(s.cfg.Root, BlocksDir) | ||||
| @@ -115,7 +114,7 @@ func (s *Local) ListAll() ([]types.FileInfo, error) { | |||||
| return infos, nil | return infos, nil | ||||
| } | } | ||||
| func (s *Local) Purge(removes []cdssdk.FileHash) error { | |||||
| func (s *ShardStore) Purge(removes []cdssdk.FileHash) error { | |||||
| for _, hash := range removes { | for _, hash := range removes { | ||||
| fileName := string(hash) | fileName := string(hash) | ||||
| @@ -130,19 +129,19 @@ func (s *Local) Purge(removes []cdssdk.FileHash) error { | |||||
| return nil | return nil | ||||
| } | } | ||||
| func (s *Local) Stats() types.Stats { | |||||
| func (s *ShardStore) Stats() types.Stats { | |||||
| // TODO 统计本地存储的相关信息 | // TODO 统计本地存储的相关信息 | ||||
| return types.Stats{ | return types.Stats{ | ||||
| Status: types.StatusOK, | Status: types.StatusOK, | ||||
| } | } | ||||
| } | } | ||||
| func (s *Local) onWritterAbort(w *Writer) { | |||||
| func (s *ShardStore) onWritterAbort(w *ShardWriter) { | |||||
| logger.Debugf("writting file %v aborted", w.path) | logger.Debugf("writting file %v aborted", w.path) | ||||
| s.removeTempFile(w.path) | s.removeTempFile(w.path) | ||||
| } | } | ||||
| func (s *Local) onWritterFinish(w *Writer, hash cdssdk.FileHash) (types.FileInfo, error) { | |||||
| func (s *ShardStore) onWritterFinish(w *ShardWriter, hash cdssdk.FileHash) (types.FileInfo, error) { | |||||
| logger.Debugf("write file %v finished, size: %v, hash: %v", w.path, w.size, hash) | logger.Debugf("write file %v finished, size: %v, hash: %v", w.path, w.size, hash) | ||||
| blockDir := filepath.Join(s.cfg.Root, BlocksDir, string(hash)[:2]) | blockDir := filepath.Join(s.cfg.Root, BlocksDir, string(hash)[:2]) | ||||
| @@ -168,7 +167,7 @@ func (s *Local) onWritterFinish(w *Writer, hash cdssdk.FileHash) (types.FileInfo | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func (s *Local) removeTempFile(path string) { | |||||
| func (s *ShardStore) removeTempFile(path string) { | |||||
| err := os.Remove(path) | err := os.Remove(path) | ||||
| if err != nil { | if err != nil { | ||||
| logger.Warnf("removing temp file %v: %v", path, err) | logger.Warnf("removing temp file %v: %v", path, err) | ||||
| @@ -1,4 +1,4 @@ | |||||
| package tempstore | |||||
| package local | |||||
| import cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | import cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -8,19 +8,19 @@ import ( | |||||
| "strings" | "strings" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| type Writer struct { | |||||
| type ShardWriter struct { | |||||
| path string | path string | ||||
| file *os.File | file *os.File | ||||
| hasher hash.Hash | hasher hash.Hash | ||||
| size int64 | size int64 | ||||
| closed bool | closed bool | ||||
| owner *Local | |||||
| owner *ShardStore | |||||
| } | } | ||||
| func (w *Writer) Write(data []byte) (int, error) { | |||||
| func (w *ShardWriter) Write(data []byte) (int, error) { | |||||
| n, err := w.file.Write(data) | n, err := w.file.Write(data) | ||||
| if err != nil { | if err != nil { | ||||
| return 0, err | return 0, err | ||||
| @@ -32,7 +32,7 @@ func (w *Writer) Write(data []byte) (int, error) { | |||||
| } | } | ||||
| // 取消写入 | // 取消写入 | ||||
| func (w *Writer) Abort() error { | |||||
| func (w *ShardWriter) Abort() error { | |||||
| if w.closed { | if w.closed { | ||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -44,7 +44,7 @@ func (w *Writer) Abort() error { | |||||
| } | } | ||||
| // 结束写入,获得文件哈希值 | // 结束写入,获得文件哈希值 | ||||
| func (w *Writer) Finish() (types.FileInfo, error) { | |||||
| func (w *ShardWriter) Finish() (types.FileInfo, error) { | |||||
| if w.closed { | if w.closed { | ||||
| return types.FileInfo{}, fmt.Errorf("stream closed") | return types.FileInfo{}, fmt.Errorf("stream closed") | ||||
| } | } | ||||
| @@ -5,14 +5,14 @@ import ( | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | stgmod "gitlink.org.cn/cloudream/storage/common/models" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/storages/local" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/local" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | ||||
| ) | ) | ||||
| func createShardStore(detail stgmod.StorageDetail, ch *types.StorageEventChan, stg *storage) error { | func createShardStore(detail stgmod.StorageDetail, ch *types.StorageEventChan, stg *storage) error { | ||||
| switch confg := detail.Shard.Config.(type) { | switch confg := detail.Shard.Config.(type) { | ||||
| case *cdssdk.LocalShardStorage: | case *cdssdk.LocalShardStorage: | ||||
| store, err := local.New(detail.Storage, *confg) | |||||
| store, err := local.NewShardStore(detail.Storage, *confg) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("new local shard store: %v", err) | return fmt.Errorf("new local shard store: %v", err) | ||||
| } | } | ||||
| @@ -9,9 +9,7 @@ import ( | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/reflect2" | "gitlink.org.cn/cloudream/common/utils/reflect2" | ||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | stgmod "gitlink.org.cn/cloudream/storage/common/models" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shared" | |||||
| stypes "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| var ErrStorageNotFound = errors.New("storage not found") | var ErrStorageNotFound = errors.New("storage not found") | ||||
| @@ -22,20 +20,20 @@ var ErrStorageExists = errors.New("storage already exists") | |||||
| type storage struct { | type storage struct { | ||||
| Shard types.ShardStore | Shard types.ShardStore | ||||
| Shared shared.SharedStore | |||||
| Components []stypes.StorageComponent | |||||
| Shared types.SharedStore | |||||
| Components []types.StorageComponent | |||||
| } | } | ||||
| type Manager struct { | type Manager struct { | ||||
| storages map[cdssdk.StorageID]*storage | storages map[cdssdk.StorageID]*storage | ||||
| lock sync.Mutex | lock sync.Mutex | ||||
| eventChan *stypes.StorageEventChan | |||||
| eventChan *types.StorageEventChan | |||||
| } | } | ||||
| func NewManager() *Manager { | func NewManager() *Manager { | ||||
| return &Manager{ | return &Manager{ | ||||
| storages: make(map[cdssdk.StorageID]*storage), | storages: make(map[cdssdk.StorageID]*storage), | ||||
| eventChan: async.NewUnboundChannel[stypes.StorageEvent](), | |||||
| eventChan: async.NewUnboundChannel[types.StorageEvent](), | |||||
| } | } | ||||
| } | } | ||||
| @@ -108,7 +106,7 @@ func (m *Manager) GetShardStore(stgID cdssdk.StorageID) (types.ShardStore, error | |||||
| } | } | ||||
| // 查找指定Storage的SharedStore组件 | // 查找指定Storage的SharedStore组件 | ||||
| func (m *Manager) GetSharedStore(stgID cdssdk.StorageID) (shared.SharedStore, error) { | |||||
| func (m *Manager) GetSharedStore(stgID cdssdk.StorageID) (types.SharedStore, error) { | |||||
| m.lock.Lock() | m.lock.Lock() | ||||
| defer m.lock.Unlock() | defer m.lock.Unlock() | ||||
| @@ -125,7 +123,7 @@ func (m *Manager) GetSharedStore(stgID cdssdk.StorageID) (shared.SharedStore, er | |||||
| } | } | ||||
| // 查找指定Storage的指定类型的组件,可以是ShardStore、SharedStore、或者其他自定义的组件 | // 查找指定Storage的指定类型的组件,可以是ShardStore、SharedStore、或者其他自定义的组件 | ||||
| func (m *Manager) GetComponent(stgID cdssdk.StorageID, typ reflect.Type) (stypes.StorageComponent, error) { | |||||
| func (m *Manager) GetComponent(stgID cdssdk.StorageID, typ reflect.Type) (types.StorageComponent, error) { | |||||
| m.lock.Lock() | m.lock.Lock() | ||||
| defer m.lock.Unlock() | defer m.lock.Unlock() | ||||
| @@ -141,7 +139,7 @@ func (m *Manager) GetComponent(stgID cdssdk.StorageID, typ reflect.Type) (stypes | |||||
| } | } | ||||
| return stg.Shard, nil | return stg.Shard, nil | ||||
| case reflect2.TypeOf[shared.SharedStore](): | |||||
| case reflect2.TypeOf[types.SharedStore](): | |||||
| if stg.Shared == nil { | if stg.Shared == nil { | ||||
| return nil, ErrComponentNotFound | return nil, ErrComponentNotFound | ||||
| } | } | ||||
| @@ -158,7 +156,7 @@ func (m *Manager) GetComponent(stgID cdssdk.StorageID, typ reflect.Type) (stypes | |||||
| } | } | ||||
| } | } | ||||
| func GetComponent[T stypes.StorageComponent](mgr *Manager, stgID cdssdk.StorageID) (T, error) { | |||||
| func GetComponent[T types.StorageComponent](mgr *Manager, stgID cdssdk.StorageID) (T, error) { | |||||
| ret, err := mgr.GetComponent(stgID, reflect2.TypeOf[T]()) | ret, err := mgr.GetComponent(stgID, reflect2.TypeOf[T]()) | ||||
| if err != nil { | if err != nil { | ||||
| var def T | var def T | ||||
| @@ -1,26 +0,0 @@ | |||||
| package utils | |||||
| import "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| type errorWriter struct { | |||||
| err error | |||||
| } | |||||
| func (w *errorWriter) Write(data []byte) (int, error) { | |||||
| return 0, w.err | |||||
| } | |||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | |||||
| // 方便defer机制 | |||||
| func (w *errorWriter) Abort() error { | |||||
| return w.err | |||||
| } | |||||
| // 结束写入,获得文件哈希值 | |||||
| func (w *errorWriter) Finish() (types.FileInfo, error) { | |||||
| return types.FileInfo{}, w.err | |||||
| } | |||||
| func ErrorWriter(err error) types.Writer { | |||||
| return &errorWriter{err: err} | |||||
| } | |||||
| @@ -1,58 +0,0 @@ | |||||
| package types | |||||
| import ( | |||||
| "fmt" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| ) | |||||
| type OpenOption struct { | |||||
| FileHash cdssdk.FileHash | |||||
| Offset int64 | |||||
| Length int64 | |||||
| } | |||||
| func NewOpen(fileHash cdssdk.FileHash) OpenOption { | |||||
| return OpenOption{ | |||||
| FileHash: fileHash, | |||||
| Offset: 0, | |||||
| Length: -1, | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) WithLength(len int64) OpenOption { | |||||
| o.Length = len | |||||
| return *o | |||||
| } | |||||
| // [start, end],即包含end | |||||
| func (o *OpenOption) WithRange(start int64, end int64) OpenOption { | |||||
| o.Offset = start | |||||
| o.Length = end - start + 1 | |||||
| return *o | |||||
| } | |||||
| func (o *OpenOption) WithNullableLength(offset int64, length *int64) { | |||||
| o.Offset = offset | |||||
| if length != nil { | |||||
| o.Length = *length | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) String() string { | |||||
| rangeStart := "" | |||||
| if o.Offset > 0 { | |||||
| rangeStart = fmt.Sprintf("%d", o.Offset) | |||||
| } | |||||
| rangeEnd := "" | |||||
| if o.Length >= 0 { | |||||
| rangeEnd = fmt.Sprintf("%d", o.Offset+o.Length-1) | |||||
| } | |||||
| if rangeStart == "" && rangeEnd == "" { | |||||
| return string(o.FileHash) | |||||
| } | |||||
| return fmt.Sprintf("%s[%s:%s]", string(o.FileHash), rangeStart, rangeEnd) | |||||
| } | |||||
| @@ -1,7 +0,0 @@ | |||||
| package shared | |||||
| import "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| type SharedStore interface { | |||||
| types.StorageComponent | |||||
| } | |||||
| @@ -1,4 +0,0 @@ | |||||
| package tempstore | |||||
| type TempStore interface { | |||||
| } | |||||
| @@ -1,10 +1,10 @@ | |||||
| package types | package types | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "io" | "io" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| type Status interface { | type Status interface { | ||||
| @@ -23,9 +23,9 @@ type StoreEvent interface { | |||||
| } | } | ||||
| type ShardStore interface { | type ShardStore interface { | ||||
| types.StorageComponent | |||||
| StorageComponent | |||||
| // 准备写入一个新文件,写入后获得FileHash | // 准备写入一个新文件,写入后获得FileHash | ||||
| New() Writer | |||||
| New() ShardWriter | |||||
| // 使用F函数创建Option对象 | // 使用F函数创建Option对象 | ||||
| Open(opt OpenOption) (io.ReadCloser, error) | Open(opt OpenOption) (io.ReadCloser, error) | ||||
| // 获取所有文件信息,尽量保证操作是原子的 | // 获取所有文件信息,尽量保证操作是原子的 | ||||
| @@ -61,7 +61,7 @@ type Stats struct { | |||||
| Description string | Description string | ||||
| } | } | ||||
| type Writer interface { | |||||
| type ShardWriter interface { | |||||
| io.Writer | io.Writer | ||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | ||||
| // 方便defer机制 | // 方便defer机制 | ||||
| @@ -69,3 +69,54 @@ type Writer interface { | |||||
| // 结束写入,获得文件哈希值 | // 结束写入,获得文件哈希值 | ||||
| Finish() (FileInfo, error) | Finish() (FileInfo, error) | ||||
| } | } | ||||
| type OpenOption struct { | |||||
| FileHash cdssdk.FileHash | |||||
| Offset int64 | |||||
| Length int64 | |||||
| } | |||||
| func NewOpen(fileHash cdssdk.FileHash) OpenOption { | |||||
| return OpenOption{ | |||||
| FileHash: fileHash, | |||||
| Offset: 0, | |||||
| Length: -1, | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) WithLength(len int64) OpenOption { | |||||
| o.Length = len | |||||
| return *o | |||||
| } | |||||
| // [start, end],即包含end | |||||
| func (o *OpenOption) WithRange(start int64, end int64) OpenOption { | |||||
| o.Offset = start | |||||
| o.Length = end - start + 1 | |||||
| return *o | |||||
| } | |||||
| func (o *OpenOption) WithNullableLength(offset int64, length *int64) { | |||||
| o.Offset = offset | |||||
| if length != nil { | |||||
| o.Length = *length | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) String() string { | |||||
| rangeStart := "" | |||||
| if o.Offset > 0 { | |||||
| rangeStart = fmt.Sprintf("%d", o.Offset) | |||||
| } | |||||
| rangeEnd := "" | |||||
| if o.Length >= 0 { | |||||
| rangeEnd = fmt.Sprintf("%d", o.Offset+o.Length-1) | |||||
| } | |||||
| if rangeStart == "" && rangeEnd == "" { | |||||
| return string(o.FileHash) | |||||
| } | |||||
| return fmt.Sprintf("%s[%s:%s]", string(o.FileHash), rangeStart, rangeEnd) | |||||
| } | |||||
| @@ -0,0 +1,5 @@ | |||||
| package types | |||||
| type SharedStore interface { | |||||
| StorageComponent | |||||
| } | |||||
| @@ -0,0 +1,5 @@ | |||||
| package types | |||||
| type TempStore interface { | |||||
| StorageComponent | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package utils | |||||
| import "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| type errorShardWriter struct { | |||||
| err error | |||||
| } | |||||
| func (w *errorShardWriter) Write(data []byte) (int, error) { | |||||
| return 0, w.err | |||||
| } | |||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | |||||
| // 方便defer机制 | |||||
| func (w *errorShardWriter) Abort() error { | |||||
| return w.err | |||||
| } | |||||
| // 结束写入,获得文件哈希值 | |||||
| func (w *errorShardWriter) Finish() (types.FileInfo, error) { | |||||
| return types.FileInfo{}, w.err | |||||
| } | |||||
| func ErrorShardWriter(err error) types.ShardWriter { | |||||
| return &errorShardWriter{err: err} | |||||
| } | |||||