You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

models.go 10 kB

11 months ago
1 year ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. package cdssdk
  2. import (
  3. "database/sql/driver"
  4. "fmt"
  5. "time"
  6. "github.com/samber/lo"
  7. "gitlink.org.cn/cloudream/common/pkgs/types"
  8. "gitlink.org.cn/cloudream/common/utils/serder"
  9. )
  10. const (
  11. ObjectPathSeparator = "/"
  12. )
  13. type HubID int64
  14. type PackageID int64
  15. type ObjectID int64
  16. type UserID int64
  17. type BucketID int64
  18. type StorageID int64
  19. type LocationID int64
  20. // 文件的SHA256哈希值,全大写的16进制字符串格式
  21. type FileHash string
  22. /// TODO 将分散在各处的公共结构体定义集中到这里来
  23. type Redundancy interface {
  24. }
  25. var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Redundancy](
  26. (*NoneRedundancy)(nil),
  27. (*RepRedundancy)(nil),
  28. (*ECRedundancy)(nil),
  29. (*LRCRedundancy)(nil),
  30. (*SegmentRedundancy)(nil),
  31. )), "type")
  32. type NoneRedundancy struct {
  33. serder.Metadata `union:"none"`
  34. Type string `json:"type"`
  35. }
  36. func NewNoneRedundancy() *NoneRedundancy {
  37. return &NoneRedundancy{
  38. Type: "none",
  39. }
  40. }
  41. func (b *NoneRedundancy) Value() (driver.Value, error) {
  42. return serder.ObjectToJSONEx[Redundancy](b)
  43. }
  44. var DefaultRepRedundancy = *NewRepRedundancy(2)
  45. type RepRedundancy struct {
  46. serder.Metadata `union:"rep"`
  47. Type string `json:"type"`
  48. RepCount int `json:"repCount"`
  49. }
  50. func NewRepRedundancy(repCount int) *RepRedundancy {
  51. return &RepRedundancy{
  52. Type: "rep",
  53. RepCount: repCount,
  54. }
  55. }
  56. func (b *RepRedundancy) Value() (driver.Value, error) {
  57. return serder.ObjectToJSONEx[Redundancy](b)
  58. }
  59. var DefaultECRedundancy = *NewECRedundancy(2, 3, 1024*1024*5)
  60. type ECRedundancy struct {
  61. serder.Metadata `union:"ec"`
  62. Type string `json:"type"`
  63. K int `json:"k"`
  64. N int `json:"n"`
  65. ChunkSize int `json:"chunkSize"`
  66. }
  67. func NewECRedundancy(k int, n int, chunkSize int) *ECRedundancy {
  68. return &ECRedundancy{
  69. Type: "ec",
  70. K: k,
  71. N: n,
  72. ChunkSize: chunkSize,
  73. }
  74. }
  75. func (b *ECRedundancy) Value() (driver.Value, error) {
  76. return serder.ObjectToJSONEx[Redundancy](b)
  77. }
  78. func (b *ECRedundancy) StripSize() int64 {
  79. return int64(b.ChunkSize) * int64(b.K)
  80. }
  81. var DefaultLRCRedundancy = *NewLRCRedundancy(2, 4, []int{2}, 1024*1024*5)
  82. type LRCRedundancy struct {
  83. serder.Metadata `union:"lrc"`
  84. Type string `json:"type"`
  85. K int `json:"k"`
  86. N int `json:"n"`
  87. Groups []int `json:"groups"`
  88. ChunkSize int `json:"chunkSize"`
  89. }
  90. func NewLRCRedundancy(k int, n int, groups []int, chunkSize int) *LRCRedundancy {
  91. return &LRCRedundancy{
  92. Type: "lrc",
  93. K: k,
  94. N: n,
  95. Groups: groups,
  96. ChunkSize: chunkSize,
  97. }
  98. }
  99. func (b *LRCRedundancy) Value() (driver.Value, error) {
  100. return serder.ObjectToJSONEx[Redundancy](b)
  101. }
  102. // 判断指定块属于哪个组。如果都不属于,则返回-1。
  103. func (b *LRCRedundancy) FindGroup(idx int) int {
  104. if idx >= b.N-len(b.Groups) {
  105. return idx - (b.N - len(b.Groups))
  106. }
  107. for i, group := range b.Groups {
  108. if idx < group {
  109. return i
  110. }
  111. idx -= group
  112. }
  113. return -1
  114. }
  115. // M = N - len(Groups),即数据块+校验块的总数,不包括组校验块。
  116. func (b *LRCRedundancy) M() int {
  117. return b.N - len(b.Groups)
  118. }
  119. func (b *LRCRedundancy) GetGroupElements(grp int) []int {
  120. var idxes []int
  121. grpStart := 0
  122. for i := 0; i < grp; i++ {
  123. grpStart += b.Groups[i]
  124. }
  125. for i := 0; i < b.Groups[grp]; i++ {
  126. idxes = append(idxes, grpStart+i)
  127. }
  128. idxes = append(idxes, b.N-len(b.Groups)+grp)
  129. return idxes
  130. }
  131. type SegmentRedundancy struct {
  132. serder.Metadata `union:"segment"`
  133. Type string `json:"type"`
  134. Segments []int64 `json:"segments"` // 每一段的大小
  135. }
  136. func NewSegmentRedundancy(totalSize int64, segmentCount int) *SegmentRedundancy {
  137. var segs []int64
  138. segLen := int64(0)
  139. // 计算每一段的大小。大小不一定都相同,但总和应该等于总大小。
  140. for i := 0; i < segmentCount; i++ {
  141. curLen := totalSize*int64(i+1)/int64(segmentCount) - segLen
  142. segs = append(segs, curLen)
  143. segLen += curLen
  144. }
  145. return &SegmentRedundancy{
  146. Type: "segment",
  147. Segments: segs,
  148. }
  149. }
  150. func (r *SegmentRedundancy) SegmentCount() int {
  151. return len(r.Segments)
  152. }
  153. func (r *SegmentRedundancy) CalcSegmentStart(index int) int64 {
  154. return lo.Sum(r.Segments[:index])
  155. }
  156. // 计算指定位置取整到最近的段的起始位置。
  157. func (r *SegmentRedundancy) FloorSegmentPosition(pos int64) int64 {
  158. fpos := int64(0)
  159. for _, segLen := range r.Segments {
  160. segEnd := fpos + segLen
  161. if pos < segEnd {
  162. break
  163. }
  164. fpos += segLen
  165. }
  166. return fpos
  167. }
  168. // 计算指定范围内的段索引范围,参数和返回值所代表的范围都是左闭右开的。
  169. // 如果end == -1,则代表计算从start到最后一个字节的范围。
  170. func (b *SegmentRedundancy) CalcSegmentRange(start int64, end *int64) (segIdxStart int, segIdxEnd int) {
  171. segIdxStart = len(b.Segments)
  172. segIdxEnd = len(b.Segments)
  173. // 找到第一个包含start的段索引
  174. segStart := int64(0)
  175. for i, segLen := range b.Segments {
  176. segEnd := segStart + segLen
  177. if start < segEnd {
  178. segIdxStart = i
  179. break
  180. }
  181. segStart += segLen
  182. }
  183. if end != nil {
  184. // 找到第一个包含end的段索引
  185. segStart = int64(0)
  186. for i, segLen := range b.Segments {
  187. segEnd := segStart + segLen
  188. if *end <= segEnd {
  189. segIdxEnd = i + 1
  190. break
  191. }
  192. segStart += segLen
  193. }
  194. }
  195. return
  196. }
  197. const (
  198. PackageStateNormal = "Normal"
  199. PackageStateDeleted = "Deleted"
  200. )
  201. type Package struct {
  202. PackageID PackageID `gorm:"column:PackageID; primaryKey; type:bigint; autoIncrement" json:"packageID"`
  203. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  204. BucketID BucketID `gorm:"column:BucketID; type:bigint; not null" json:"bucketID"`
  205. State string `gorm:"column:State; type:varchar(255); not null" json:"state"`
  206. }
  207. func (Package) TableName() string {
  208. return "Package"
  209. }
  210. type Object struct {
  211. ObjectID ObjectID `json:"objectID" gorm:"column:ObjectID; primaryKey; type:bigint; autoIncrement" `
  212. PackageID PackageID `json:"packageID" gorm:"column:PackageID; type:bigint; not null"`
  213. Path string `json:"path" gorm:"column:Path; type:varchar(1024); not null"`
  214. Size int64 `json:"size,string" gorm:"column:Size; type:bigint; not null"`
  215. FileHash FileHash `json:"fileHash" gorm:"column:FileHash; type:char(64); not null"`
  216. Redundancy Redundancy `json:"redundancy" gorm:"column:Redundancy; type: json; serializer:union"`
  217. CreateTime time.Time `json:"createTime" gorm:"column:CreateTime; type:datetime; not null"`
  218. UpdateTime time.Time `json:"updateTime" gorm:"column:UpdateTime; type:datetime; not null"`
  219. }
  220. func (Object) TableName() string {
  221. return "Object"
  222. }
  223. type Hub struct {
  224. HubID HubID `gorm:"column:HubID; primaryKey; type:bigint; autoIncrement" json:"hubID"`
  225. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  226. Address HubAddressInfo `gorm:"column:Address; type:json; serializer:union" json:"address"`
  227. LocationID LocationID `gorm:"column:LocationID; type:bigint; not null" json:"locationID"`
  228. State string `gorm:"column:State; type:varchar(255); not null" json:"state"`
  229. LastReportTime *time.Time `gorm:"column:LastReportTime; type:datetime" json:"lastReportTime"`
  230. }
  231. func (Hub) TableName() string {
  232. return "Hub"
  233. }
  234. type HubAddressInfo interface {
  235. }
  236. var HubAddressUnion = types.NewTypeUnion[HubAddressInfo](
  237. (*GRPCAddressInfo)(nil),
  238. (*HttpAddressInfo)(nil),
  239. )
  240. var _ = serder.UseTypeUnionInternallyTagged(&HubAddressUnion, "type")
  241. type GRPCAddressInfo struct {
  242. serder.Metadata `union:"GRPC"`
  243. Type string `json:"type"`
  244. LocalIP string `json:"localIP"`
  245. ExternalIP string `json:"externalIP"`
  246. LocalGRPCPort int `json:"localGRPCPort"`
  247. ExternalGRPCPort int `json:"externalGRPCPort"`
  248. }
  249. type HttpAddressInfo struct {
  250. serder.Metadata `union:"HTTP"`
  251. Type string `json:"type"`
  252. LocalIP string `json:"localIP"`
  253. ExternalIP string `json:"externalIP"`
  254. Port int `json:"port"`
  255. }
  256. func (n Hub) String() string {
  257. return fmt.Sprintf("%v(%v)", n.Name, n.HubID)
  258. }
  259. type PinnedObject struct {
  260. ObjectID ObjectID `gorm:"column:ObjectID; primaryKey; type:bigint" json:"objectID"`
  261. StorageID StorageID `gorm:"column:StorageID; primaryKey; type:bigint" json:"storageID"`
  262. CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
  263. }
  264. func (PinnedObject) TableName() string {
  265. return "PinnedObject"
  266. }
  267. type Bucket struct {
  268. BucketID BucketID `gorm:"column:BucketID; primaryKey; type:bigint; autoIncrement" json:"bucketID"`
  269. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  270. CreatorID UserID `gorm:"column:CreatorID; type:bigint; not null" json:"creatorID"`
  271. }
  272. func (Bucket) TableName() string {
  273. return "Bucket"
  274. }
  275. type HubConnectivity struct {
  276. FromHubID HubID `gorm:"column:FromHubID; primaryKey; type:bigint" json:"fromHubID"`
  277. ToHubID HubID `gorm:"column:ToHubID; primaryKey; type:bigint" json:"ToHubID"`
  278. Delay *float32 `gorm:"column:Delay; type:float" json:"delay"`
  279. TestTime time.Time `gorm:"column:TestTime; type:datetime" json:"testTime"`
  280. }
  281. func (HubConnectivity) TableName() string {
  282. return "HubConnectivity"
  283. }
  284. type StoragePackageCachingInfo struct {
  285. StorageID StorageID `json:"storageID"`
  286. FileSize int64 `json:"fileSize"`
  287. ObjectCount int64 `json:"objectCount"`
  288. }
  289. type PackageCachingInfo struct {
  290. StorageInfos []StoragePackageCachingInfo `json:"stgInfos"`
  291. PackageSize int64 `json:"packageSize"`
  292. }
  293. func NewPackageCachingInfo(stgInfos []StoragePackageCachingInfo, packageSize int64) PackageCachingInfo {
  294. return PackageCachingInfo{
  295. StorageInfos: stgInfos,
  296. PackageSize: packageSize,
  297. }
  298. }
  299. type CodeError struct {
  300. Code string `json:"code"`
  301. Message string `json:"message"`
  302. }
  303. func (e *CodeError) Error() string {
  304. return fmt.Sprintf("code: %s, message: %s", e.Code, e.Message)
  305. }