|
- package plans
-
- import (
- "fmt"
-
- "github.com/google/uuid"
- stgmod "gitlink.org.cn/cloudream/storage/common/models"
- "gitlink.org.cn/cloudream/storage/common/pkgs/db/model"
- "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
- "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/ops"
- )
-
- type StreamInfo struct {
- ID ioswitch.StreamID
- }
-
- type PlanBuilder struct {
- streams []*StreamInfo
- agentPlans map[int64]*AgentPlanBuilder
- }
-
- func (b *PlanBuilder) Build() (*ComposedPlan, error) {
- planID := uuid.NewString()
-
- var agentPlans []AgentPlan
- for _, b := range b.agentPlans {
- plan, err := b.Build(ioswitch.PlanID(planID))
- if err != nil {
- return nil, err
- }
-
- agentPlans = append(agentPlans, plan)
- }
-
- return &ComposedPlan{
- ID: ioswitch.PlanID(planID),
- AgentPlans: agentPlans,
- }, nil
- }
-
- func (b *PlanBuilder) newStream() *StreamInfo {
- str := &StreamInfo{
- ID: ioswitch.StreamID(fmt.Sprintf("%d", len(b.streams)+1)),
- }
-
- b.streams = append(b.streams, str)
-
- return str
- }
-
- func NewPlanBuilder() PlanBuilder {
- return PlanBuilder{
- agentPlans: make(map[int64]*AgentPlanBuilder),
- }
- }
-
- func (b *PlanBuilder) FromExecutor() *FromExecutorStream {
- return &FromExecutorStream{
- owner: b,
- info: b.newStream(),
- }
- }
-
- func (b *PlanBuilder) AtAgent(node model.Node) *AgentPlanBuilder {
- agtPlan, ok := b.agentPlans[node.NodeID]
- if !ok {
- agtPlan = &AgentPlanBuilder{
- owner: b,
- node: node,
- }
- b.agentPlans[node.NodeID] = agtPlan
- }
-
- return agtPlan
- }
-
- type FromExecutorStream struct {
- owner *PlanBuilder
- info *StreamInfo
- toNode *model.Node
- }
-
- func (s *FromExecutorStream) ToNode(node model.Node) *AgentStream {
- s.toNode = &node
- return &AgentStream{
- owner: s.owner.AtAgent(node),
- info: s.info,
- }
- }
-
- type ToExecutorStream struct {
- info *StreamInfo
- fromNode *model.Node
- }
-
- type AgentStream struct {
- owner *AgentPlanBuilder
- info *StreamInfo
- }
-
- func (s *AgentStream) IPFSWrite(resultKey string) {
- s.owner.ops = append(s.owner.ops, &ops.IPFSWrite{
- Input: s.info.ID,
- ResultKey: resultKey,
- })
- }
-
- func (s *AgentStream) GRPCSend(node model.Node) *AgentStream {
- agtStr := &AgentStream{
- owner: s.owner.owner.AtAgent(node),
- info: s.info,
- }
-
- s.owner.ops = append(s.owner.ops, &ops.GRPCSend{
- StreamID: s.info.ID,
- Node: node,
- })
-
- return agtStr
- }
-
- func (s *AgentStream) ToExecutor() *ToExecutorStream {
- return &ToExecutorStream{
- info: s.info,
- fromNode: &s.owner.node,
- }
- }
-
- type AgentPlanBuilder struct {
- owner *PlanBuilder
- node model.Node
- ops []ioswitch.Op
- }
-
- func (b *AgentPlanBuilder) GRCPFetch(node model.Node) *AgentStream {
- agtStr := &AgentStream{
- owner: b,
- info: b.owner.newStream(),
- }
-
- b.ops = append(b.ops, &ops.GRPCFetch{
- StreamID: agtStr.info.ID,
- Node: node,
- })
-
- return agtStr
- }
-
- func (b *AgentPlanBuilder) IPFSRead(fileHash string) *AgentStream {
- agtStr := &AgentStream{
- owner: b,
- info: b.owner.newStream(),
- }
-
- b.ops = append(b.ops, &ops.IPFSRead{
- Output: agtStr.info.ID,
- FileHash: fileHash,
- })
-
- return agtStr
- }
-
- func (b *AgentPlanBuilder) ECCompute(ec stgmod.EC, inBlockIndexes []int, outBlockIndexes []int, streams ...*AgentStream) *MultiStream {
- mstr := &MultiStream{}
-
- var inputStrIDs []ioswitch.StreamID
- for _, str := range streams {
- inputStrIDs = append(inputStrIDs, str.info.ID)
- }
-
- var outputStrIDs []ioswitch.StreamID
- for i := 0; i < ec.N-ec.K; i++ {
- info := b.owner.newStream()
- mstr.streams[i] = &AgentStream{
- owner: b,
- info: info,
- }
- outputStrIDs = append(outputStrIDs, info.ID)
- }
-
- b.ops = append(b.ops, &ops.ECCompute{
- EC: ec,
- InputIDs: inputStrIDs,
- OutputIDs: outputStrIDs,
- InputBlockIndexes: inBlockIndexes,
- OutputBlockIndexes: outBlockIndexes,
- })
-
- return mstr
- }
-
- func (b *AgentPlanBuilder) Combine(length int64, streams ...*AgentStream) *AgentStream {
- agtStr := &AgentStream{
- owner: b,
- info: b.owner.newStream(),
- }
-
- var inputStrIDs []ioswitch.StreamID
- for _, str := range streams {
- inputStrIDs = append(inputStrIDs, str.info.ID)
- }
-
- b.ops = append(b.ops, &ops.Combine{
- InputIDs: inputStrIDs,
- OutputID: agtStr.info.ID,
- Length: length,
- })
-
- return agtStr
- }
-
- func (b *AgentPlanBuilder) Build(planID ioswitch.PlanID) (AgentPlan, error) {
- plan := ioswitch.Plan{
- ID: planID,
- Ops: b.ops,
- }
-
- return AgentPlan{
- Plan: plan,
- Node: b.node,
- }, nil
- }
-
- type MultiStream struct {
- streams []*AgentStream
- }
-
- func (m *MultiStream) Stream(index int) *AgentStream {
- return m.streams[index]
- }
|