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  }