JCS-pub/common/types/client.go

259 lines
8.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package jcstypes
import (
"fmt"
"time"
"github.com/samber/lo"
"gitlink.org.cn/cloudream/common/utils/sort2"
)
const (
ObjectPathSeparator = "/"
)
type PackageID int64
type ObjectID int64
type BucketID int64
type UserSpaceID int64
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"`
CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
}
func (Bucket) TableName() string {
return "Bucket"
}
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"`
CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
}
func (Package) TableName() string {
return "Package"
}
type Object struct {
ObjectID ObjectID `json:"objectID" gorm:"column:ObjectID; primaryKey; type:bigint; autoIncrement" `
PackageID PackageID `json:"packageID" gorm:"column:PackageID; type:bigint; not null"`
Path string `json:"path" gorm:"column:Path; type:varchar(1024); not null"`
Size int64 `json:"size,string" gorm:"column:Size; type:bigint; not null"`
FileHash FileHash `json:"fileHash" gorm:"column:FileHash; type:char(68); not null"`
Redundancy Redundancy `json:"redundancy" gorm:"column:Redundancy; type: json; serializer:union"`
CreateTime time.Time `json:"createTime" gorm:"column:CreateTime; type:datetime; not null"`
UpdateTime time.Time `json:"updateTime" gorm:"column:UpdateTime; type:datetime; not null"`
}
func (Object) TableName() string {
return "Object"
}
type ObjectBlock struct {
ObjectID ObjectID `gorm:"column:ObjectID; primaryKey; type:bigint" json:"objectID"`
Index int `gorm:"column:Index; primaryKey; type:int" json:"index"`
// 这个块应该在哪个空间中
UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"userSpaceID"`
FileHash FileHash `gorm:"column:FileHash; type:char(68); not null" json:"fileHash"`
Size int64 `gorm:"column:Size; type:bigint" json:"size"`
}
func (ObjectBlock) TableName() string {
return "ObjectBlock"
}
type UserSpace struct {
UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"userSpaceID"`
// 用户空间名称
Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
// 用户空间所在的存储服务配置
Storage StorageType `gorm:"column:Storage; type:json; not null; serializer:union" json:"storage"`
// 用户在指定存储节点的凭证信息比如用户账户AK/SK等
Credential StorageCredential `gorm:"column:Credential; type:json; not null; serializer:union" json:"credential"`
// 用户空间的分片存储配置,如果为空,则表示不使用分片存储
ShardStore *ShardStoreUserConfig `gorm:"column:ShardStore; type:json; serializer:json" json:"shardStore"`
// 存储服务特性功能的配置
Features []StorageFeature `json:"features" gorm:"column:Features; type:json; serializer:union"`
// 各种组件保存数据的根目录。组件工作过程中都会以这个目录为根除了BaseStore
WorkingDir JPath `gorm:"column:WorkingDir; type:varchar(1024); not null; serializer:string" json:"workingDir"`
// 工作目录在存储系统中的真实路径。当工作路径在挂载点内时,这个字段记录的是挂载背后的真实路径。部分直接与存储系统交互的组件需要知道真实路径。
// RealWorkingDir string `gorm:"column:RealWorkingDir; type:varchar(1024); not null" json:"realWorkingDir"`
// 用户空间信息的版本号,每一次更改都需要更新版本号
Revision int64 `gorm:"column:Revision; type:bigint; not null" json:"revision"`
}
func (UserSpace) TableName() string {
return "UserSpace"
}
func (s UserSpace) String() string {
return fmt.Sprintf("%v[id=%v,storage=%v,rev=%v]", s.Name, s.UserSpaceID, s.Storage, s.Revision)
}
type PackageAccessStat struct {
PackageID PackageID `gorm:"column:PackageID; primaryKey; type:bigint" json:"packageID"`
// 发起读取调度的用户空间ID
UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"storageID"`
// 前一日的读取量的滑动平均值
Amount float64 `gorm:"column:Amount; type:double" json:"amount"`
// 当日的读取量
Counter float64 `gorm:"column:Counter; type:double" json:"counter"`
}
func (PackageAccessStat) TableName() string {
return "PackageAccessStat"
}
type ObjectAccessStat struct {
ObjectID ObjectID `gorm:"column:ObjectID; primaryKey; type:bigint" json:"objectID"`
// 发起读取调度的用户空间ID
UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"userStorageID"`
// 前一日的读取量的滑动平均值
Amount float64 `gorm:"column:Amount; type:float; not null" json:"amount"`
// 当日的读取量
Counter float64 `gorm:"column:Counter; type:float; not null" json:"counter"`
}
func (ObjectAccessStat) TableName() string {
return "ObjectAccessStat"
}
type PinnedObject struct {
ObjectID ObjectID `gorm:"column:ObjectID; primaryKey; type:bigint" json:"objectID"`
UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"userSpaceID"`
CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
}
func (PinnedObject) TableName() string {
return "PinnedObject"
}
type ObjectDetail struct {
Object Object `json:"object"`
PinnedAt []UserSpaceID `json:"pinnedAt"`
Blocks []ObjectBlock `json:"blocks"`
}
func NewObjectDetail(object Object, pinnedAt []UserSpaceID, blocks []ObjectBlock) ObjectDetail {
return ObjectDetail{
Object: object,
PinnedAt: pinnedAt,
Blocks: blocks,
}
}
func DetailsFromObjects(objects []Object) []ObjectDetail {
details := make([]ObjectDetail, len(objects))
for i, object := range objects {
details[i] = ObjectDetail{
Object: object,
}
}
return details
}
// 将blocks放到对应的object中。要求objs和blocks都按ObjectID升序
func DetailsFillObjectBlocks(objs []ObjectDetail, blocks []ObjectBlock) {
blksCur := 0
for i := range objs {
obj := &objs[i]
// 1. 查询Object和ObjectBlock时均按照ObjectID升序排序
// 2. ObjectBlock结果集中的不同ObjectID数只会比Object结果集的少
// 因此在两个结果集上同时从头开始遍历时如果两边的ObjectID字段不同那么一定是ObjectBlock这边的ObjectID > Object的ObjectID
// 此时让Object的遍历游标前进直到两边的ObjectID再次相等
for ; blksCur < len(blocks); blksCur++ {
if blocks[blksCur].ObjectID != obj.Object.ObjectID {
break
}
obj.Blocks = append(obj.Blocks, blocks[blksCur])
}
}
}
// 将pinnedAt放到对应的object中。要求objs和pinnedAt都按ObjectID升序
func DetailsFillPinnedAt(objs []ObjectDetail, pinnedAt []PinnedObject) {
pinnedCur := 0
for i := range objs {
obj := &objs[i]
for ; pinnedCur < len(pinnedAt); pinnedCur++ {
if pinnedAt[pinnedCur].ObjectID != obj.Object.ObjectID {
break
}
obj.PinnedAt = append(obj.PinnedAt, pinnedAt[pinnedCur].UserSpaceID)
}
}
}
type GrouppedObjectBlock struct {
ObjectID ObjectID
Index int
FileHash FileHash
Size int64
UserSpaceIDs []UserSpaceID
}
func (o *ObjectDetail) GroupBlocks() []GrouppedObjectBlock {
grps := make(map[int]GrouppedObjectBlock)
for _, block := range o.Blocks {
grp, ok := grps[block.Index]
if !ok {
grp = GrouppedObjectBlock{
ObjectID: block.ObjectID,
Index: block.Index,
FileHash: block.FileHash,
Size: block.Size,
}
}
grp.UserSpaceIDs = append(grp.UserSpaceIDs, block.UserSpaceID)
grps[block.Index] = grp
}
return sort2.Sort(lo.Values(grps), func(l, r GrouppedObjectBlock) int { return l.Index - r.Index })
}
func (o *ObjectDetail) ContainsBlock(idx int, userSpaceID UserSpaceID) bool {
for _, block := range o.Blocks {
if block.Index == idx && block.UserSpaceID == userSpaceID {
return true
}
}
return false
}
func (o *ObjectDetail) ContainsPinned(userSpaceID UserSpaceID) bool {
for _, spaceID := range o.PinnedAt {
if spaceID == userSpaceID {
return true
}
}
return false
}
type UserSpaceDetail struct {
UserID UserID
UserSpace UserSpace
RecommendHub *Hub
}
func (d UserSpaceDetail) String() string {
return d.UserSpace.String()
}
type PackageDetail struct {
Package Package
ObjectCount int64
TotalSize int64
}
type SpaceToSpaceResult struct {
Success []string `json:"success"`
Failed []string `json:"failed"`
}