rpc: add cache to basic parameters

Need to cache values of string, bool, int and array because they can be
reused multiple times by RPC handlers. Other values don't need to be
cached.
This commit is contained in:
Anna Shaleva 2021-10-28 17:24:38 +03:00
parent 2fd04fbb35
commit 867bb708fc

View file

@ -23,6 +23,7 @@ type (
// the client. // the client.
Param struct { Param struct {
json.RawMessage json.RawMessage
cache interface{}
} }
// FuncParam represents a function argument parameter used in the // FuncParam represents a function argument parameter used in the
@ -86,12 +87,18 @@ func (p *Param) GetStringStrict() (string, error) {
if p.IsNull() { if p.IsNull() {
return "", errNotAString return "", errNotAString
} }
var s string if p.cache == nil {
err := json.Unmarshal(p.RawMessage, &s) var s string
if err != nil { err := json.Unmarshal(p.RawMessage, &s)
return "", errNotAString if err != nil {
return "", errNotAString
}
p.cache = s
} }
return s, nil if s, ok := p.cache.(string); ok {
return s, nil
}
return "", errNotAString
} }
// GetString returns string value of the parameter or tries to cast parameter to a string value. // GetString returns string value of the parameter or tries to cast parameter to a string value.
@ -102,25 +109,40 @@ func (p *Param) GetString() (string, error) {
if p.IsNull() { if p.IsNull() {
return "", errNotAString return "", errNotAString
} }
var s string if p.cache == nil {
err := json.Unmarshal(p.RawMessage, &s) var s string
if err == nil { err := json.Unmarshal(p.RawMessage, &s)
return s, nil if err == nil {
p.cache = s
} else {
var i int
err = json.Unmarshal(p.RawMessage, &i)
if err == nil {
p.cache = i
} else {
var b bool
err = json.Unmarshal(p.RawMessage, &b)
if err == nil {
p.cache = b
} else {
return "", errNotAString
}
}
}
} }
var i int switch t := p.cache.(type) {
err = json.Unmarshal(p.RawMessage, &i) case string:
if err == nil { return t, nil
return strconv.Itoa(i), nil case int:
} return strconv.Itoa(t), nil
var b bool case bool:
err = json.Unmarshal(p.RawMessage, &b) if t {
if err == nil {
if b {
return "true", nil return "true", nil
} }
return "false", nil return "false", nil
default:
return "", errNotAString
} }
return "", errNotAString
} }
// GetBooleanStrict returns boolean value of the parameter. // GetBooleanStrict returns boolean value of the parameter.
@ -129,9 +151,11 @@ func (p *Param) GetBooleanStrict() (bool, error) {
return false, errMissingParameter return false, errMissingParameter
} }
if bytes.Equal(p.RawMessage, jsonTrueBytes) { if bytes.Equal(p.RawMessage, jsonTrueBytes) {
p.cache = true
return true, nil return true, nil
} }
if bytes.Equal(p.RawMessage, jsonFalseBytes) { if bytes.Equal(p.RawMessage, jsonFalseBytes) {
p.cache = false
return false, nil return false, nil
} }
return false, errNotABool return false, errNotABool
@ -146,21 +170,36 @@ func (p *Param) GetBoolean() (bool, error) {
return false, errNotABool return false, errNotABool
} }
var b bool var b bool
err := json.Unmarshal(p.RawMessage, &b) if p.cache == nil {
if err == nil { err := json.Unmarshal(p.RawMessage, &b)
return b, nil if err == nil {
p.cache = b
} else {
var s string
err = json.Unmarshal(p.RawMessage, &s)
if err == nil {
p.cache = s
} else {
var i int
err = json.Unmarshal(p.RawMessage, &i)
if err == nil {
p.cache = i
} else {
return false, errNotABool
}
}
}
} }
var s string switch t := p.cache.(type) {
err = json.Unmarshal(p.RawMessage, &s) case bool:
if err == nil { return t, nil
return s != "", nil case string:
return t != "", nil
case int:
return t != 0, nil
default:
return false, errNotABool
} }
var i int
err = json.Unmarshal(p.RawMessage, &i)
if err == nil {
return i != 0, nil
}
return false, errNotABool
} }
// GetIntStrict returns int value of the parameter if the parameter is integer. // GetIntStrict returns int value of the parameter if the parameter is integer.
@ -171,12 +210,18 @@ func (p *Param) GetIntStrict() (int, error) {
if p.IsNull() { if p.IsNull() {
return 0, errNotAnInt return 0, errNotAnInt
} }
var i int if p.cache == nil {
err := json.Unmarshal(p.RawMessage, &i) var i int
if err != nil { err := json.Unmarshal(p.RawMessage, &i)
return i, errNotAnInt if err != nil {
return i, errNotAnInt
}
p.cache = i
} }
return i, nil if i, ok := p.cache.(int); ok {
return i, nil
}
return 0, errNotAnInt
} }
// GetInt returns int value of the parameter or tries to cast parameter to an int value. // GetInt returns int value of the parameter or tries to cast parameter to an int value.
@ -187,26 +232,40 @@ func (p *Param) GetInt() (int, error) {
if p.IsNull() { if p.IsNull() {
return 0, errNotAnInt return 0, errNotAnInt
} }
var i int if p.cache == nil {
err := json.Unmarshal(p.RawMessage, &i) var i int
if err == nil { err := json.Unmarshal(p.RawMessage, &i)
return i, nil if err == nil {
} p.cache = i
var s string } else {
err = json.Unmarshal(p.RawMessage, &s) var s string
if err == nil { err = json.Unmarshal(p.RawMessage, &s)
return strconv.Atoi(s) if err == nil {
} p.cache = s
var b bool } else {
err = json.Unmarshal(p.RawMessage, &b) var b bool
if err == nil { err = json.Unmarshal(p.RawMessage, &b)
i = 0 if err == nil {
if b { p.cache = b
i = 1 } else {
return 0, errNotAnInt
}
}
} }
return i, nil
} }
return 0, errNotAnInt switch t := p.cache.(type) {
case int:
return t, nil
case string:
return strconv.Atoi(t)
case bool:
if t {
return 1, nil
}
return 0, nil
default:
return 0, errNotAnInt
}
} }
// GetArray returns a slice of Params stored in the parameter. // GetArray returns a slice of Params stored in the parameter.
@ -217,12 +276,18 @@ func (p *Param) GetArray() ([]Param, error) {
if p.IsNull() { if p.IsNull() {
return nil, errNotAnArray return nil, errNotAnArray
} }
a := []Param{} if p.cache == nil {
err := json.Unmarshal(p.RawMessage, &a) a := []Param{}
if err != nil { err := json.Unmarshal(p.RawMessage, &a)
return nil, errNotAnArray if err != nil {
return nil, errNotAnArray
}
p.cache = a
} }
return a, nil if a, ok := p.cache.([]Param); ok {
return a, nil
}
return nil, errNotAnArray
} }
// GetUint256 returns Uint256 value of the parameter. // GetUint256 returns Uint256 value of the parameter.
@ -274,6 +339,7 @@ func (p *Param) GetFuncParam() (FuncParam, error) {
if p == nil { if p == nil {
return FuncParam{}, errMissingParameter return FuncParam{}, errMissingParameter
} }
// This one doesn't need to be cached, it's used only once.
fp := FuncParam{} fp := FuncParam{}
err := json.Unmarshal(p.RawMessage, &fp) err := json.Unmarshal(p.RawMessage, &fp)
return fp, err return fp, err
@ -303,6 +369,7 @@ func (p *Param) GetBytesBase64() ([]byte, error) {
// GetSignerWithWitness returns SignerWithWitness value of the parameter. // GetSignerWithWitness returns SignerWithWitness value of the parameter.
func (p *Param) GetSignerWithWitness() (SignerWithWitness, error) { func (p *Param) GetSignerWithWitness() (SignerWithWitness, error) {
// This one doesn't need to be cached, it's used only once.
aux := new(signerWithWitnessAux) aux := new(signerWithWitnessAux)
err := json.Unmarshal(p.RawMessage, aux) err := json.Unmarshal(p.RawMessage, aux)
if err != nil { if err != nil {