github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/pehrest/hash-get-values.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package pehrest 4 5 import ( 6 "../authorization" 7 "../convert" 8 "../protocol" 9 "../srpc" 10 "../syllab" 11 ) 12 13 // HashGetValuesService store details about HashGetValues service 14 var HashGetValuesService = service.Service{ 15 URN: "urn:giti:index.protocol:service:hash-get-values", 16 Domain: DomainName, 17 ID: 6441982709696635966, 18 IssueDate: 1587282740, 19 ExpiryDate: 0, 20 ExpireInFavorOfURN: "", 21 ExpireInFavorOfID: 0, 22 Status: protocol.Software_PreAlpha, 23 24 Authorization: authorization.Service{ 25 CRUD: authorization.CRUDRead, 26 UserType: protocol.UserType_App, 27 }, 28 29 Detail: map[protocol.LanguageID]service.ServiceDetail{ 30 protocol.LanguageEnglish: { 31 Name: "Index Hash - Get Values", 32 Description: `Get related RecordsID that set to given indexHash before. 33 Request 32 RecordsID to given IndexKey even if just one of them use! 34 Suggest not get more than 65536 related RecordID in single request!`, 35 TAGS: []string{}, 36 }, 37 }, 38 39 SRPCHandler: HashGetValuesSRPC, 40 } 41 42 // HashGetValues get related RecordsID that set to given IndexKey before. 43 func HashGetValues(req HashGetValuesReq) (res HashGetValuesRes, err protocol.Error) { 44 var node protocol.ApplicationNode 45 node, err = protocol.App.GetNodeByStorage(req.MediaTypeID, req.IndexKey) 46 if err != nil { 47 return 48 } 49 50 if node.Node.State == protocol.ApplicationState_LocalNode { 51 res, err = HashGetValues(req) 52 return 53 } 54 55 var st protocol.Stream 56 st, err = node.Conn.MakeOutcomeStream(0) 57 if err != nil { 58 return 59 } 60 61 st.Service = &HashGetValuesService 62 st.OutcomePayload = req.ToSyllab() 63 64 err = node.Conn.Send(st) 65 if err != nil { 66 return 67 } 68 69 res = &HashGetValuesRes{} 70 res.FromSyllab(srpc.GetPayload(st.IncomePayload)) 71 return 72 } 73 74 // HashGetValuesSRPC is sRPC handler of HashGetValues service. 75 func HashGetValuesSRPC(st protocol.Stream) { 76 if st.Connection.UserID != protocol.OS.AppManifest().AppUUID() { 77 // TODO::: Attack?? 78 err = authorization.ErrUserNotAllow 79 return 80 } 81 82 var req = &HashGetValuesReq{} 83 req.FromSyllab(srpc.GetPayload(st.IncomePayload)) 84 85 var res *HashGetValuesRes 86 res, err = HashGetValues(req) 87 // Check if any error occur in bussiness logic 88 if err != nil { 89 return 90 } 91 92 st.OutcomePayload = res.ToSyllab() 93 } 94 95 // HashGetValuesReq is request structure of HashGetValues() 96 type HashGetValuesReq struct { 97 IndexKey [32]byte 98 Offset uint64 99 Limit uint64 // It is better to be modulus of 32||128 if storage devices use 4K clusters! 100 } 101 102 // HashGetValuesRes is response structure of HashGetValues() 103 type HashGetValuesRes struct { 104 IndexValues [][32]byte 105 } 106 107 // HashGetValues returns related IndexValues that set to given indexKey before in local storages. 108 func HashGetValues(req *HashGetValuesReq) (res *HashGetValuesRes, err protocol.Error) { 109 var hashIndex = IndexHash{ 110 RecordID: req.IndexKey, 111 } 112 113 res = &HashGetValuesRes{} 114 res.IndexValues, err = hashIndex.Get(req.Offset, req.Limit) 115 return 116 } 117 118 /* 119 -- Syllab Encoder & Decoder -- 120 */ 121 122 // FromSyllab decode from buf to req 123 // Due to this service just use internally, It skip check buf size syllab rule! Panic occur if bad request received! 124 func (req *HashGetValuesReq) FromSyllab(payload []byte, stackIndex uint32) { 125 copy(req.IndexKey[:], buf[:]) 126 req.Offset = syllab.GetUInt64(buf, 32) 127 req.Limit = syllab.GetUInt64(buf, 40) 128 } 129 130 // ToSyllab encode req to buf 131 func (req *HashGetValuesReq) ToSyllab(payload []byte, stackIndex, heapIndex uint32) (freeHeapIndex uint32) { 132 buf = make([]byte, req.LenAsSyllab()+4) // +4 for sRPC ID instead get offset argument 133 copy(buf[4:], req.IndexKey[:]) 134 syllab.SetUInt64(buf, 36, req.Offset) 135 syllab.SetUInt64(buf, 44, req.Limit) 136 return 137 } 138 139 func (req *HashGetValuesReq) LenOfSyllabStack() uint32 { 140 return 48 141 } 142 143 func (req *HashGetValuesReq) LenOfSyllabHeap() (ln uint32) { 144 return 145 } 146 147 func (req *HashGetValuesReq) LenAsSyllab() uint64 { 148 return uint64(req.LenOfSyllabStack() + req.LenOfSyllabHeap()) 149 } 150 151 // FromSyllab decode from buf to req 152 // Due to this service just use internally, It skip check buf size syllab rule! Panic occur if bad request received! 153 func (res *HashGetValuesRes) FromSyllab(payload []byte, stackIndex uint32) { 154 buf = buf[8:] 155 res.IndexValues = convert.UnsafeByteSliceTo32ByteArraySlice(buf) 156 } 157 158 // ToSyllab encode res to buf 159 func (res *HashGetValuesRes) ToSyllab(payload []byte, stackIndex, heapIndex uint32) (freeHeapIndex uint32) { 160 // Due to just have one field in res structure we skip set address of res.IndexValues in buf 161 // syllab.SetUInt32(buf, 4, res.LenOfSyllabStack()) 162 syllab.SetUInt32(buf, 8, uint32(len(res.IndexValues))) 163 copy(buf[res.LenOfSyllabStack():], convert.Unsafe32ByteArraySliceToByteSlice(res.IndexValues)) 164 return 165 } 166 167 func (res *HashGetValuesRes) LenOfSyllabStack() uint32 { 168 return 8 169 } 170 171 func (res *HashGetValuesRes) LenOfSyllabHeap() (ln uint32) { 172 ln = uint32(len(res.IndexValues) * 32) 173 return 174 } 175 176 func (res *HashGetValuesRes) LenAsSyllab() uint64 { 177 return uint64(res.LenOfSyllabStack() + res.LenOfSyllabHeap()) 178 }