github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/ec/intrareq.go (about) 1 // Package ec provides erasure coding (EC) based data protection for AIStore. 2 /* 3 * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package ec 6 7 import ( 8 "github.com/NVIDIA/aistore/cmn/cos" 9 "github.com/NVIDIA/aistore/core/meta" 10 "github.com/NVIDIA/aistore/memsys" 11 ) 12 13 const ( 14 // a target sends a replica or slice to store on another target 15 // the destionation does not have to respond 16 reqPut intraReqType = iota 17 // response for requested slice/replica by another target 18 respPut 19 // a target requests a slice or replica from another target 20 // if the destination has the object/slice it sends it back, otherwise 21 // it sets Exists=false in response header 22 reqGet 23 // a target cleans up the object and notifies all other targets to do 24 // cleanup as well. Destinations do not have to respond 25 reqDel 26 ) 27 28 type ( 29 // type of EC request between targets. If the destination has to respond it 30 // must set the same request type in response header 31 intraReqType = int 32 33 // An EC request sent via transport using Opaque field of transport.ObjHdr 34 // between targets inside a cluster 35 intraReq struct { 36 // Object metadata, used when a target copies replicas/slices after 37 // encoding or restoring the object data 38 meta *Metadata 39 // Used only by destination to answer to the sender if the destination 40 // has the requested metafile or replica/slice 41 exists bool 42 // The sent data is slice or full replica 43 isSlice bool 44 // bucket ID 45 bid uint64 46 } 47 ) 48 49 // interface guard 50 var ( 51 _ cos.Unpacker = (*intraReq)(nil) 52 _ cos.Packer = (*intraReq)(nil) 53 ) 54 55 // Create a request header: initializes the `Sender` field with local target's 56 // daemon ID, and sets `Exists:true` that means "local object exists". 57 // Later `Exists` can be changed to `false` if local file is unreadable or does 58 // not exist 59 func newIntraReq(act intraReqType, meta *Metadata, bck *meta.Bck) *intraReq { 60 req := &intraReq{ 61 meta: meta, 62 exists: true, 63 } 64 if bck != nil && bck.Props != nil { 65 req.bid = bck.Props.BID 66 } 67 if act == reqGet && meta != nil { 68 req.isSlice = !meta.IsCopy 69 } 70 return req 71 } 72 73 func (r *intraReq) PackedSize() int { 74 if r.meta == nil { 75 // int8+int8+ptr_marker 76 return 3 + cos.SizeofI64 77 } 78 // int8+int8+ptr_marker+sizeof(meta) 79 return r.meta.PackedSize() + 3 + cos.SizeofI64 80 } 81 82 func (r *intraReq) Pack(packer *cos.BytePack) { 83 packer.WriteBool(r.exists) 84 packer.WriteBool(r.isSlice) 85 packer.WriteUint64(r.bid) 86 if r.meta == nil { 87 packer.WriteByte(0) 88 } else { 89 packer.WriteByte(1) 90 packer.WriteAny(r.meta) 91 } 92 } 93 94 func (r *intraReq) Unpack(unpacker *cos.ByteUnpack) error { 95 var ( 96 i byte 97 err error 98 ) 99 if r.exists, err = unpacker.ReadBool(); err != nil { 100 return err 101 } 102 if r.isSlice, err = unpacker.ReadBool(); err != nil { 103 return err 104 } 105 if r.bid, err = unpacker.ReadUint64(); err != nil { 106 return err 107 } 108 if i, err = unpacker.ReadByte(); err != nil { 109 return err 110 } 111 if i == 0 { 112 r.meta = nil 113 return nil 114 } 115 r.meta = NewMetadata() 116 return unpacker.ReadAny(r.meta) 117 } 118 119 func (r *intraReq) NewPack(mm *memsys.MMSA) []byte { 120 var ( 121 buf []byte 122 l = r.PackedSize() 123 ) 124 if mm != nil { 125 buf, _ = mm.AllocSize(int64(l)) 126 } 127 packer := cos.NewPacker(buf, l) 128 packer.WriteAny(r) 129 return packer.Bytes() 130 }