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

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