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 11 kB

11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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/math2"
  9. "gitlink.org.cn/cloudream/common/utils/serder"
  10. )
  11. const (
  12. ObjectPathSeparator = "/"
  13. )
  14. type HubID int64
  15. type PackageID int64
  16. type ObjectID int64
  17. type UserID int64
  18. type BucketID int64
  19. type StorageID int64
  20. type LocationID int64
  21. /// TODO 将分散在各处的公共结构体定义集中到这里来
  22. type Redundancy interface {
  23. }
  24. var RedundancyUnion = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Redundancy](
  25. (*NoneRedundancy)(nil),
  26. (*RepRedundancy)(nil),
  27. (*ECRedundancy)(nil),
  28. (*LRCRedundancy)(nil),
  29. (*SegmentRedundancy)(nil),
  30. (*MultipartUploadRedundancy)(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. return &SegmentRedundancy{
  138. Type: "segment",
  139. Segments: math2.SplitN(totalSize, segmentCount),
  140. }
  141. }
  142. func (r *SegmentRedundancy) SegmentCount() int {
  143. return len(r.Segments)
  144. }
  145. func (r *SegmentRedundancy) CalcSegmentStart(index int) int64 {
  146. return lo.Sum(r.Segments[:index])
  147. }
  148. // 计算指定位置取整到最近的段的起始位置。
  149. func (r *SegmentRedundancy) FloorSegmentPosition(pos int64) int64 {
  150. fpos := int64(0)
  151. for _, segLen := range r.Segments {
  152. segEnd := fpos + segLen
  153. if pos < segEnd {
  154. break
  155. }
  156. fpos += segLen
  157. }
  158. return fpos
  159. }
  160. // 计算指定范围内的段索引范围,参数和返回值所代表的范围都是左闭右开的。
  161. // 如果end == -1,则代表计算从start到最后一个字节的范围。
  162. func (b *SegmentRedundancy) CalcSegmentRange(start int64, end *int64) (segIdxStart int, segIdxEnd int) {
  163. segIdxStart = len(b.Segments)
  164. segIdxEnd = len(b.Segments)
  165. // 找到第一个包含start的段索引
  166. segStart := int64(0)
  167. for i, segLen := range b.Segments {
  168. segEnd := segStart + segLen
  169. if start < segEnd {
  170. segIdxStart = i
  171. break
  172. }
  173. segStart += segLen
  174. }
  175. if end != nil {
  176. // 找到第一个包含end的段索引
  177. segStart = int64(0)
  178. for i, segLen := range b.Segments {
  179. segEnd := segStart + segLen
  180. if *end <= segEnd {
  181. segIdxEnd = i + 1
  182. break
  183. }
  184. segStart += segLen
  185. }
  186. }
  187. return
  188. }
  189. type MultipartUploadRedundancy struct {
  190. serder.Metadata `union:"multipartUpload"`
  191. Type string `json:"type"`
  192. }
  193. func NewMultipartUploadRedundancy() *MultipartUploadRedundancy {
  194. return &MultipartUploadRedundancy{
  195. Type: "multipartUpload",
  196. }
  197. }
  198. type User struct {
  199. UserID UserID `gorm:"column:UserID; primaryKey; type:bigint" json:"userID"`
  200. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  201. Password string `gorm:"column:Password; type:varchar(255); not null" json:"password"`
  202. }
  203. func (User) TableName() string {
  204. return "User"
  205. }
  206. const (
  207. PackageStateNormal = "Normal"
  208. PackageStateDeleted = "Deleted"
  209. )
  210. type Package struct {
  211. PackageID PackageID `gorm:"column:PackageID; primaryKey; type:bigint; autoIncrement" json:"packageID"`
  212. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  213. BucketID BucketID `gorm:"column:BucketID; type:bigint; not null" json:"bucketID"`
  214. CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
  215. State string `gorm:"column:State; type:varchar(255); not null" json:"state"`
  216. }
  217. func (Package) TableName() string {
  218. return "Package"
  219. }
  220. type Object struct {
  221. ObjectID ObjectID `json:"objectID" gorm:"column:ObjectID; primaryKey; type:bigint; autoIncrement" `
  222. PackageID PackageID `json:"packageID" gorm:"column:PackageID; type:bigint; not null"`
  223. Path string `json:"path" gorm:"column:Path; type:varchar(1024); not null"`
  224. Size int64 `json:"size,string" gorm:"column:Size; type:bigint; not null"`
  225. FileHash FileHash `json:"fileHash" gorm:"column:FileHash; type:char(68); not null"`
  226. Redundancy Redundancy `json:"redundancy" gorm:"column:Redundancy; type: json; serializer:union"`
  227. CreateTime time.Time `json:"createTime" gorm:"column:CreateTime; type:datetime; not null"`
  228. UpdateTime time.Time `json:"updateTime" gorm:"column:UpdateTime; type:datetime; not null"`
  229. }
  230. func (Object) TableName() string {
  231. return "Object"
  232. }
  233. type Hub struct {
  234. HubID HubID `gorm:"column:HubID; primaryKey; type:bigint; autoIncrement" json:"hubID"`
  235. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  236. Address HubAddressInfo `gorm:"column:Address; type:json; serializer:union" json:"address"`
  237. LocationID LocationID `gorm:"column:LocationID; type:bigint; not null" json:"locationID"`
  238. State string `gorm:"column:State; type:varchar(255); not null" json:"state"`
  239. LastReportTime *time.Time `gorm:"column:LastReportTime; type:datetime" json:"lastReportTime"`
  240. }
  241. func (Hub) TableName() string {
  242. return "Hub"
  243. }
  244. type HubAddressInfo interface {
  245. }
  246. var HubAddressUnion = types.NewTypeUnion[HubAddressInfo](
  247. (*GRPCAddressInfo)(nil),
  248. (*HttpAddressInfo)(nil),
  249. )
  250. var _ = serder.UseTypeUnionInternallyTagged(&HubAddressUnion, "type")
  251. type GRPCAddressInfo struct {
  252. serder.Metadata `union:"GRPC"`
  253. Type string `json:"type"`
  254. LocalIP string `json:"localIP"`
  255. ExternalIP string `json:"externalIP"`
  256. LocalGRPCPort int `json:"localGRPCPort"`
  257. ExternalGRPCPort int `json:"externalGRPCPort"`
  258. }
  259. type HttpAddressInfo struct {
  260. serder.Metadata `union:"HTTP"`
  261. Type string `json:"type"`
  262. LocalIP string `json:"localIP"`
  263. ExternalIP string `json:"externalIP"`
  264. Port int `json:"port"`
  265. }
  266. func (n Hub) String() string {
  267. return fmt.Sprintf("%v(%v)", n.Name, n.HubID)
  268. }
  269. type PinnedObject struct {
  270. ObjectID ObjectID `gorm:"column:ObjectID; primaryKey; type:bigint" json:"objectID"`
  271. StorageID StorageID `gorm:"column:StorageID; primaryKey; type:bigint" json:"storageID"`
  272. CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
  273. }
  274. func (PinnedObject) TableName() string {
  275. return "PinnedObject"
  276. }
  277. type Bucket struct {
  278. BucketID BucketID `gorm:"column:BucketID; primaryKey; type:bigint; autoIncrement" json:"bucketID"`
  279. Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
  280. CreateTime time.Time `gorm:"column:CreateTime; type:datetime; not null" json:"createTime"`
  281. CreatorID UserID `gorm:"column:CreatorID; type:bigint; not null" json:"creatorID"`
  282. }
  283. func (Bucket) TableName() string {
  284. return "Bucket"
  285. }
  286. type HubConnectivity struct {
  287. FromHubID HubID `gorm:"column:FromHubID; primaryKey; type:bigint" json:"fromHubID"`
  288. ToHubID HubID `gorm:"column:ToHubID; primaryKey; type:bigint" json:"ToHubID"`
  289. Latency *float32 `gorm:"column:Latency; type:float" json:"latency"`
  290. TestTime time.Time `gorm:"column:TestTime; type:datetime" json:"testTime"`
  291. }
  292. func (HubConnectivity) TableName() string {
  293. return "HubConnectivity"
  294. }
  295. type StoragePackageCachingInfo struct {
  296. StorageID StorageID `json:"storageID"`
  297. FileSize int64 `json:"fileSize"`
  298. ObjectCount int64 `json:"objectCount"`
  299. }
  300. type PackageCachingInfo struct {
  301. StorageInfos []StoragePackageCachingInfo `json:"stgInfos"`
  302. PackageSize int64 `json:"packageSize"`
  303. }
  304. func NewPackageCachingInfo(stgInfos []StoragePackageCachingInfo, packageSize int64) PackageCachingInfo {
  305. return PackageCachingInfo{
  306. StorageInfos: stgInfos,
  307. PackageSize: packageSize,
  308. }
  309. }
  310. type CodeError struct {
  311. Code string `json:"code"`
  312. Message string `json:"message"`
  313. }
  314. func (e *CodeError) Error() string {
  315. return fmt.Sprintf("code: %s, message: %s", e.Code, e.Message)
  316. }
  317. type PackageHash struct {
  318. // 16进制字符串格式的sha256哈希值
  319. Hash string `json:"hash"`
  320. }
  321. type UserStats struct {
  322. UserID UserID `json:"userID" gorm:"column:UserID"`
  323. FileCount int64 `json:"fileCount" gorm:"column:FileCount"`
  324. TotalSize int64 `json:"totalSize" gorm:"column:TotalSize"`
  325. }