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.

node.go 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. package dag
  2. import (
  3. "github.com/samber/lo"
  4. "gitlink.org.cn/cloudream/common/utils/lo2"
  5. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/exec"
  6. )
  7. type NodeEnvType string
  8. const (
  9. EnvAny NodeEnvType = ""
  10. EnvDriver NodeEnvType = "Driver"
  11. EnvWorker NodeEnvType = "Worker"
  12. )
  13. type NodeEnv struct {
  14. Type NodeEnvType
  15. Worker exec.WorkerInfo
  16. Pinned bool // 如果为true,则不应该改变这个节点的执行环境
  17. }
  18. func (e *NodeEnv) ToEnvUnknown(pinned bool) {
  19. e.Type = EnvAny
  20. e.Worker = nil
  21. e.Pinned = pinned
  22. }
  23. func (e *NodeEnv) ToEnvDriver(pinned bool) {
  24. e.Type = EnvDriver
  25. e.Worker = nil
  26. e.Pinned = pinned
  27. }
  28. func (e *NodeEnv) ToEnvWorker(worker exec.WorkerInfo, pinned bool) {
  29. e.Type = EnvWorker
  30. e.Worker = worker
  31. e.Pinned = pinned
  32. }
  33. func (e *NodeEnv) CopyFrom(other *NodeEnv) {
  34. e.Type = other.Type
  35. e.Worker = other.Worker
  36. e.Pinned = other.Pinned
  37. }
  38. func (e *NodeEnv) Equals(other *NodeEnv) bool {
  39. if e.Type != other.Type {
  40. return false
  41. }
  42. if e.Type != EnvWorker {
  43. return true
  44. }
  45. return e.Worker.Equals(other.Worker)
  46. }
  47. type Node interface {
  48. Graph() *Graph
  49. SetGraph(graph *Graph)
  50. Env() *NodeEnv
  51. InputStreams() *StreamInputSlots
  52. OutputStreams() *StreamOutputSlots
  53. InputValues() *ValueInputSlots
  54. OutputValues() *ValueOutputSlots
  55. GenerateOp() (exec.Op, error)
  56. // String() string
  57. }
  58. type VarSlots[T any] []*T
  59. func (s *VarSlots[T]) Len() int {
  60. return len(*s)
  61. }
  62. func (s *VarSlots[T]) Get(idx int) *T {
  63. return (*s)[idx]
  64. }
  65. func (s *VarSlots[T]) Set(idx int, val *T) *T {
  66. old := (*s)[idx]
  67. (*s)[idx] = val
  68. return old
  69. }
  70. func (s *VarSlots[T]) IndexOf(v *T) int {
  71. return lo.IndexOf(*s, v)
  72. }
  73. func (s *VarSlots[T]) Append(val *T) int {
  74. *s = append(*s, val)
  75. return s.Len() - 1
  76. }
  77. func (s *VarSlots[T]) Clear(val *T) {
  78. for i := 0; i < s.Len(); i++ {
  79. if (*s)[i] == val {
  80. (*s)[i] = nil
  81. }
  82. }
  83. }
  84. func (s *VarSlots[T]) RemoveAt(idx int) {
  85. *s = lo2.RemoveAt(*s, idx)
  86. }
  87. func (s *VarSlots[T]) RemoveRange(start int, cnt int) {
  88. *s = lo2.RemoveRange(*s, start, cnt)
  89. }
  90. func (s *VarSlots[T]) Resize(size int) {
  91. if s.Len() < size {
  92. *s = append(*s, make([]*T, size-s.Len())...)
  93. } else if s.Len() > size {
  94. *s = (*s)[:size]
  95. }
  96. }
  97. func (s *VarSlots[T]) SetRawArray(arr []*T) {
  98. *s = arr
  99. }
  100. func (s *VarSlots[T]) RawArray() []*T {
  101. return *s
  102. }
  103. type StreamInputSlots struct {
  104. Slots VarSlots[StreamVar]
  105. }
  106. func (s *StreamInputSlots) Len() int {
  107. return s.Slots.Len()
  108. }
  109. func (s *StreamInputSlots) Get(idx int) *StreamVar {
  110. return s.Slots.Get(idx)
  111. }
  112. func (s *StreamInputSlots) IndexOf(v *StreamVar) int {
  113. return s.Slots.IndexOf(v)
  114. }
  115. // 初始化输入流槽。调用者应该保证没有正在使用的槽位(即Slots的每一个元素都为nil)
  116. func (s *StreamInputSlots) Init(cnt int) {
  117. s.Slots.Resize(cnt)
  118. }
  119. func (s *StreamInputSlots) EnlargeOne() int {
  120. s.Slots.Append(nil)
  121. return s.Len() - 1
  122. }
  123. func (s *StreamInputSlots) ClearInputAt(my Node, idx int) {
  124. v := s.Get(idx)
  125. if v == nil {
  126. return
  127. }
  128. s.Slots.Set(idx, nil)
  129. v.Dst.Remove(my)
  130. }
  131. func (s *StreamInputSlots) ClearAllInput(my Node) {
  132. for i := 0; i < s.Len(); i++ {
  133. v := s.Get(i)
  134. if v == nil {
  135. continue
  136. }
  137. s.Slots.Set(i, nil)
  138. v.Dst.Remove(my)
  139. }
  140. }
  141. func (s *StreamInputSlots) GetVarIDs() []exec.VarID {
  142. var ids []exec.VarID
  143. for _, v := range s.Slots.RawArray() {
  144. if v == nil {
  145. continue
  146. }
  147. ids = append(ids, v.VarID)
  148. }
  149. return ids
  150. }
  151. func (s *StreamInputSlots) GetVarIDsRanged(start, end int) []exec.VarID {
  152. var ids []exec.VarID
  153. for i := start; i < end; i++ {
  154. v := s.Get(i)
  155. if v == nil {
  156. continue
  157. }
  158. ids = append(ids, v.VarID)
  159. }
  160. return ids
  161. }
  162. type ValueInputSlots struct {
  163. Slots VarSlots[ValueVar]
  164. }
  165. func (s *ValueInputSlots) Len() int {
  166. return s.Slots.Len()
  167. }
  168. func (s *ValueInputSlots) Get(idx int) *ValueVar {
  169. return s.Slots.Get(idx)
  170. }
  171. func (s *ValueInputSlots) IndexOf(v *ValueVar) int {
  172. return s.Slots.IndexOf(v)
  173. }
  174. // 初始化输入流槽。调用者应该保证没有正在使用的槽位(即Slots的每一个元素都为nil)
  175. func (s *ValueInputSlots) Init(cnt int) {
  176. if s.Len() < cnt {
  177. s.Slots = append(s.Slots, make([]*ValueVar, cnt-s.Len())...)
  178. }
  179. }
  180. func (s *ValueInputSlots) EnlargeOne() int {
  181. s.Slots.Append(nil)
  182. return s.Len() - 1
  183. }
  184. func (s *ValueInputSlots) ClearInputAt(my Node, idx int) {
  185. v := s.Get(idx)
  186. if v == nil {
  187. return
  188. }
  189. s.Slots.Set(idx, nil)
  190. v.Dst.Remove(my)
  191. }
  192. func (s *ValueInputSlots) GetVarIDs() []exec.VarID {
  193. var ids []exec.VarID
  194. for _, v := range s.Slots.RawArray() {
  195. if v == nil {
  196. continue
  197. }
  198. ids = append(ids, v.VarID)
  199. }
  200. return ids
  201. }
  202. func (s *ValueInputSlots) GetVarIDsStart(start int) []exec.VarID {
  203. return s.GetVarIDsRanged(start, s.Len())
  204. }
  205. func (s *ValueInputSlots) GetVarIDsRanged(start, end int) []exec.VarID {
  206. var ids []exec.VarID
  207. for i := start; i < end; i++ {
  208. v := s.Get(i)
  209. if v == nil {
  210. continue
  211. }
  212. ids = append(ids, v.VarID)
  213. }
  214. return ids
  215. }
  216. type StreamOutputSlots struct {
  217. Slots VarSlots[StreamVar]
  218. }
  219. func (s *StreamOutputSlots) Len() int {
  220. return s.Slots.Len()
  221. }
  222. func (s *StreamOutputSlots) Get(idx int) *StreamVar {
  223. return s.Slots.Get(idx)
  224. }
  225. func (s *StreamOutputSlots) IndexOf(v *StreamVar) int {
  226. return s.Slots.IndexOf(v)
  227. }
  228. // 设置Slots大小,并为每个Slot创建一个StreamVar。
  229. // 调用者应该保证没有正在使用的输出流,即每一个输出流的Dst都为空。
  230. func (s *StreamOutputSlots) Init(my Node, size int) {
  231. s.Slots.Resize(size)
  232. for i := 0; i < size; i++ {
  233. v := my.Graph().NewStreamVar()
  234. v.Src = my
  235. s.Slots.Set(i, v)
  236. }
  237. }
  238. // 在Slots末尾增加一个StreamVar,并返回它的索引
  239. func (s *StreamOutputSlots) AppendNew(my Node) StreamOutputSlot {
  240. v := my.Graph().NewStreamVar()
  241. v.Src = my
  242. s.Slots.Append(v)
  243. return StreamOutputSlot{Node: my, Index: s.Len() - 1}
  244. }
  245. // 断开指定位置的输出流到指定节点的连接
  246. func (s *StreamOutputSlots) ClearOutputAt(idx int, dst Node) {
  247. v := s.Get(idx)
  248. v.Dst.Remove(dst)
  249. dst.InputStreams().Slots.Clear(v)
  250. }
  251. // 断开所有输出流的所有连接,完全清空所有输出流。但会保留流变量
  252. func (s *StreamOutputSlots) ClearAllOutput(my Node) {
  253. for i := 0; i < s.Len(); i++ {
  254. v := s.Get(i)
  255. v.ClearAllDst()
  256. }
  257. }
  258. func (s *StreamOutputSlots) GetVarIDs() []exec.VarID {
  259. var ids []exec.VarID
  260. for _, v := range s.Slots.RawArray() {
  261. if v == nil {
  262. continue
  263. }
  264. ids = append(ids, v.VarID)
  265. }
  266. return ids
  267. }
  268. func (s *StreamOutputSlots) GetVarIDsRanged(start, end int) []exec.VarID {
  269. var ids []exec.VarID
  270. for i := start; i < end; i++ {
  271. v := s.Get(i)
  272. if v == nil {
  273. continue
  274. }
  275. ids = append(ids, v.VarID)
  276. }
  277. return ids
  278. }
  279. type ValueOutputSlots struct {
  280. Slots VarSlots[ValueVar]
  281. }
  282. func (s *ValueOutputSlots) Len() int {
  283. return s.Slots.Len()
  284. }
  285. func (s *ValueOutputSlots) Get(idx int) *ValueVar {
  286. return s.Slots.Get(idx)
  287. }
  288. func (s *ValueOutputSlots) IndexOf(v *ValueVar) int {
  289. return s.Slots.IndexOf(v)
  290. }
  291. // 设置Slots大小,并为每个Slot创建一个StreamVar
  292. // 调用者应该保证没有正在使用的输出流,即每一个输出流的Dst都为空。
  293. func (s *ValueOutputSlots) Init(my Node, size int) {
  294. s.Slots.Resize(size)
  295. for i := 0; i < size; i++ {
  296. v := my.Graph().NewValueVar()
  297. v.Src = my
  298. s.Slots.Set(i, v)
  299. }
  300. }
  301. // 在Slots末尾增加一个StreamVar,并返回它的索引
  302. func (s *ValueOutputSlots) AppendNew(my Node) ValueOutputSlot {
  303. v := my.Graph().NewValueVar()
  304. v.Src = my
  305. s.Slots.Append(v)
  306. return ValueOutputSlot{Node: my, Index: s.Len() - 1}
  307. }
  308. // 断开指定位置的输出流到指定节点的连接
  309. func (s *ValueOutputSlots) ClearOutputAt(idx int, dst Node) {
  310. v := s.Get(idx)
  311. v.Dst.Remove(dst)
  312. dst.InputValues().Slots.Clear(v)
  313. }
  314. // 断开所有输出流的所有连接,完全清空所有输出流。但会保留流变量
  315. func (s *ValueOutputSlots) ClearAllOutput(my Node) {
  316. for i := 0; i < s.Len(); i++ {
  317. v := s.Get(i)
  318. v.ClearAllDst()
  319. }
  320. }
  321. func (s *ValueOutputSlots) GetVarIDs() []exec.VarID {
  322. var ids []exec.VarID
  323. for _, v := range s.Slots.RawArray() {
  324. if v == nil {
  325. continue
  326. }
  327. ids = append(ids, v.VarID)
  328. }
  329. return ids
  330. }
  331. func (s *ValueOutputSlots) GetVarIDsRanged(start, end int) []exec.VarID {
  332. var ids []exec.VarID
  333. for i := start; i < end; i++ {
  334. v := s.Get(i)
  335. if v == nil {
  336. continue
  337. }
  338. ids = append(ids, v.VarID)
  339. }
  340. return ids
  341. }
  342. type NodeBase struct {
  343. env NodeEnv
  344. inputStreams StreamInputSlots
  345. outputStreams StreamOutputSlots
  346. inputValues ValueInputSlots
  347. outputValues ValueOutputSlots
  348. graph *Graph
  349. }
  350. func (n *NodeBase) Graph() *Graph {
  351. return n.graph
  352. }
  353. func (n *NodeBase) SetGraph(graph *Graph) {
  354. n.graph = graph
  355. }
  356. func (n *NodeBase) Env() *NodeEnv {
  357. return &n.env
  358. }
  359. func (n *NodeBase) InputStreams() *StreamInputSlots {
  360. return &n.inputStreams
  361. }
  362. func (n *NodeBase) OutputStreams() *StreamOutputSlots {
  363. return &n.outputStreams
  364. }
  365. func (n *NodeBase) InputValues() *ValueInputSlots {
  366. return &n.inputValues
  367. }
  368. func (n *NodeBase) OutputValues() *ValueOutputSlots {
  369. return &n.outputValues
  370. }
  371. type StreamOutputSlot struct {
  372. Node Node
  373. Index int
  374. }
  375. func (s StreamOutputSlot) Var() *StreamVar {
  376. return s.Node.OutputStreams().Get(s.Index)
  377. }
  378. func (s StreamOutputSlot) ToSlot(slot StreamInputSlot) {
  379. s.Var().To(slot.Node, slot.Index)
  380. }
  381. // 查询所有输出的连接的输入槽位
  382. func (s StreamOutputSlot) ListDstSlots() []StreamInputSlot {
  383. slots := make([]StreamInputSlot, s.Var().Dst.Len())
  384. myVar := s.Var()
  385. for i, dst := range s.Var().Dst {
  386. slots[i] = StreamInputSlot{Node: dst, Index: dst.InputStreams().IndexOf(myVar)}
  387. }
  388. return slots
  389. }
  390. type StreamInputSlot struct {
  391. Node Node
  392. Index int
  393. }
  394. func (s StreamInputSlot) Var() *StreamVar {
  395. return s.Node.InputStreams().Get(s.Index)
  396. }
  397. type ValueOutputSlot struct {
  398. Node Node
  399. Index int
  400. }
  401. func (s ValueOutputSlot) Var() *ValueVar {
  402. return s.Node.OutputValues().Get(s.Index)
  403. }
  404. func (s ValueOutputSlot) ToSlot(slot ValueInputSlot) {
  405. s.Var().To(slot.Node, slot.Index)
  406. }
  407. // 查询所有输出的连接的输入槽位
  408. func (s ValueOutputSlot) ListDstSlots() []ValueInputSlot {
  409. slots := make([]ValueInputSlot, s.Var().Dst.Len())
  410. myVar := s.Var()
  411. for i, dst := range s.Var().Dst {
  412. slots[i] = ValueInputSlot{Node: dst, Index: dst.InputValues().IndexOf(myVar)}
  413. }
  414. return slots
  415. }
  416. type ValueInputSlot struct {
  417. Node Node
  418. Index int
  419. }
  420. func (s ValueInputSlot) Var() *ValueVar {
  421. return s.Node.InputValues().Get(s.Index)
  422. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。