Skip to content

Commit

Permalink
feat:(thrift/generic) add option DescriptorToPathNodeWriteOptional (#…
Browse files Browse the repository at this point in the history
…39)

feat:(thrift/generic) add option `DescriptorToPathNodeWriteOptional` for API `DescriptorToPathNode()`
  • Loading branch information
AsterDY authored Jan 7, 2024
1 parent bda904c commit 497e7b3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 29 deletions.
9 changes: 7 additions & 2 deletions thrift/generic/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,18 @@ type Options struct {

// DescriptorToPathNodeMaxDepth indicates max recurse limits (>0) for API `DescriptorToPathNode`
DescriptorToPathNodeMaxDepth int

// DescriptorToPathNodeWriteOptional indicates writing empty value for optional fields for API `DescriptorToPathNode`
DescriptorToPathNodeWriteOptional bool

// DescriptorToPathNodeWriteDefualt indicates writing empty value for default fields for API `DescriptorToPathNode`
DescriptorToPathNodeWriteDefualt bool
}

var (
// StoreChildrenByIdShreshold is the maximum id to store children node by id.
StoreChildrenByIdShreshold = 256
StoreChildrenByIdShreshold = 256

// StoreChildrenByIdShreshold is the minimum id to store children node by hash.
StoreChildrenByIntHashShreshold = DefaultNodeSliceCap
)

36 changes: 21 additions & 15 deletions thrift/generic/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ func descriptorToPathNode(recurse int, desc *thrift.TypeDescriptor, root *PathNo
ns = ns[:0]
}
for _, f := range fs {
if f.Required() == thrift.OptionalRequireness && !opts.DescriptorToPathNodeWriteOptional {
continue
}
if f.Required() == thrift.DefaultRequireness && !opts.DescriptorToPathNodeWriteDefualt {
continue
}
var p PathNode
// if opts.FieldByName {
// p.Path = NewPathFieldName(f.Name())
Expand Down Expand Up @@ -365,7 +371,7 @@ func descriptorToPathNode(recurse int, desc *thrift.TypeDescriptor, root *PathNo
if ty := desc.Key().Type(); ty.IsInt() {
next[i].Path = NewPathIntKey(i) // NOTICE: use index as int key here
} else if ty == thrift.STRING {
next[i].Path = NewPathStrKey(strconv.Itoa(i))// NOTICE: use index as string key here
next[i].Path = NewPathStrKey(strconv.Itoa(i)) // NOTICE: use index as string key here
} else {
buf := thrift.NewBinaryProtocol([]byte{})
_ = buf.WriteEmpty(desc.Key()) // NOTICE: use emtpy value as binary key here
Expand Down Expand Up @@ -759,7 +765,7 @@ func (self PathNode) marshal(p *thrift.BinaryProtocol, opts *Options) error {
func guardPathNodeSlice(con *[]PathNode, l int) {
c := cap(*con)
if l >= c {
tmp := make([]PathNode, len(*con), l + DefaultNodeSliceCap)
tmp := make([]PathNode, len(*con), l+DefaultNodeSliceCap)
copy(tmp, *con)
*con = tmp
}
Expand Down Expand Up @@ -858,7 +864,7 @@ func (self *PathNode) should2(op string, t thrift.Type, t2 thrift.Type) *PathNod
if self == nil {
return errPathNode(meta.ErrNotFound, op, nil)
}
if self.Node.t != t && self.Node.t != t2{
if self.Node.t != t && self.Node.t != t2 {
return errPathNode(meta.ErrDismatchType, op, nil)
}
return nil
Expand Down Expand Up @@ -914,7 +920,7 @@ func (self *PathNode) GetByStr(key string, opts *Options) *PathNode {
// fast path: use hash to find the key.
if opts.StoreChildrenByHash {
n, _ := self.Node.len()
N := n*2
N := n * 2
// TODO: cap may change after Set. Use better way to store hash size
if cap(self.Next) >= N {
if s := getStrHash(&self.Next, key, N); s != nil {
Expand All @@ -934,7 +940,7 @@ func (self *PathNode) GetByStr(key string, opts *Options) *PathNode {

// SetByStr set the child node by string. Only support MAP with string-type key.
// If the key already exists, it will be overwritten and return true.
//
//
// If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key.
// However, if the map hash size has changed, it may fallback to O(n) search.
func (self *PathNode) SetByStr(key string, val Node, opts *Options) (bool, error) {
Expand All @@ -947,7 +953,7 @@ func (self *PathNode) SetByStr(key string, val Node, opts *Options) (bool, error
// fast path: use hash to find the key.
if opts.StoreChildrenByHash {
n, _ := self.Node.len()
N := n*2
N := n * 2
// TODO: cap may change after Set. Use better way to store hash size
if cap(self.Next) >= N {
if s := getStrHash(&self.Next, key, N); s != nil {
Expand All @@ -972,7 +978,7 @@ func (self *PathNode) SetByStr(key string, val Node, opts *Options) (bool, error
}

// GetByInt get the child node by integer. Only support MAP with integer-type key.
//
//
// If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key.
// However, if the map size has changed, it may fallback to O(n) search.
func (self *PathNode) GetByInt(key int, opts *Options) *PathNode {
Expand All @@ -986,7 +992,7 @@ func (self *PathNode) GetByInt(key int, opts *Options) *PathNode {
if opts.StoreChildrenByHash {
// TODO: size may change after Set. Use better way to store hash size
n, _ := self.Node.len()
N := n*2
N := n * 2
if cap(self.Next) >= N {
if s := getIntHash(&self.Next, uint64(key), N); s != nil {
return s
Expand Down Expand Up @@ -1018,7 +1024,7 @@ func (self *PathNode) SetByInt(key int, val Node, opts *Options) (bool, error) {
// fast path: use hash to find the key.
if opts.StoreChildrenByHash {
n, _ := self.Node.len()
N := n*2
N := n * 2
if cap(self.Next) >= N {
if s := getIntHash(&self.Next, uint64(key), N); s != nil {
s.Node = val
Expand Down Expand Up @@ -1062,8 +1068,8 @@ func (self *PathNode) Field(id thrift.FieldID, opts *Options) *PathNode {
if v.Path.t == PathFieldId && v.Path.id() == id {
return v
}
}
for i := 0; i < len(self.Next) && i<StoreChildrenByIdShreshold; i++ {
}
for i := 0; i < len(self.Next) && i < StoreChildrenByIdShreshold; i++ {
v := &self.Next[i]
if v.Path.t == PathFieldId && v.Path.id() == id {
return v
Expand Down Expand Up @@ -1096,7 +1102,7 @@ func (self *PathNode) SetField(id thrift.FieldID, val Node, opts *Options) (bool
return true, nil
}
}
for i := 0; i < len(self.Next) && i<StoreChildrenByIdShreshold; i++ {
for i := 0; i < len(self.Next) && i < StoreChildrenByIdShreshold; i++ {
v := &self.Next[i]
if v.Path.t == PathFieldId && v.Path.id() == id {
v.Node = val
Expand Down Expand Up @@ -1174,7 +1180,7 @@ func (self *PathNode) scanChildren(p *thrift.BinaryProtocol, recurse bool, opts
// fast path: use hash to store the key.
if opts.StoreChildrenByHash && size > StoreChildrenByIntHashShreshold {
// NOTE: we use original count*2 as the capacity of the hash table.
N = size*2
N = size * 2
guardPathNodeSlice(&con, N-1)
conAddr = *(*unsafe.Pointer)(unsafe.Pointer(&con))
c = N
Expand All @@ -1198,7 +1204,7 @@ func (self *PathNode) scanChildren(p *thrift.BinaryProtocol, recurse bool, opts
// fast path: use hash to store the key.
if opts.StoreChildrenByHash && size > StoreChildrenByIntHashShreshold {
// NOTE: we use original count*2 as the capacity of the hash table.
N = size*2
N = size * 2
guardPathNodeSlice(&con, N-1)
conAddr = *(*unsafe.Pointer)(unsafe.Pointer(&con))
c = N
Expand Down Expand Up @@ -1238,4 +1244,4 @@ func (self *PathNode) scanChildren(p *thrift.BinaryProtocol, recurse bool, opts

self.Next = con
return nil
}
}
22 changes: 10 additions & 12 deletions thrift/generic/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,6 @@ func checkHelper2(t *testing.T, exp []PathNode, act []PathNode, checkNode bool)
// }
// }


func DeepEqual(exp interface{}, act interface{}) bool {
switch ev := exp.(type) {
case map[int]interface{}:
Expand Down Expand Up @@ -884,7 +883,8 @@ func TestUnknownFields(t *testing.T) {
t.Run("Assgin(true, )", func(t *testing.T) {
// t.Run("allow", func(t *testing.T) {
opts := Options{
// DisallowUnknow: false,
DescriptorToPathNodeWriteDefualt: true,
DescriptorToPathNodeWriteOptional: true,
}
path := PathNode{
Node: v.Node,
Expand All @@ -897,13 +897,11 @@ func TestUnknownFields(t *testing.T) {
require.NoError(t, err)
act := PathNodeToInterface(path, &opts, true)
exp := toInterface2(sample.Example2Obj, false, b2s)
// require.Equal(t, exp, act)
if !DeepEqual(exp, act) {
spew.Dump(exp, act)
t.Fatal()
}
spew.Dump(exp, "\nnext:\n", act)
// if !DeepEqual(act, exp) {
// t.Fatal()
// }

// })
// t.Run("disallow", func(t *testing.T) {
Expand Down Expand Up @@ -1003,24 +1001,24 @@ func TestDescriptorToPathNode(t *testing.T) {
args args
wantErr bool
}{
{name:"defualt", args: args{
{name: "defualt", args: args{
desc: getExampleDesc(),
root: new(PathNode),
opts: &Options{},
}, wantErr: false},
{name:"array size 1", args: args{
{name: "array size 1", args: args{
desc: getExampleDesc(),
root: new(PathNode),
opts: &Options{
DescriptorToPathNodeArraySize: 1,
DescriptorToPathNodeMaxDepth: 256,
DescriptorToPathNodeMaxDepth: 256,
},
}, wantErr: false},
{name:"map size 1", args: args{
{name: "map size 1", args: args{
desc: getExampleDesc(),
root: new(PathNode),
opts: &Options{
DescriptorToPathNodeMapSize: 1,
DescriptorToPathNodeMapSize: 1,
DescriptorToPathNodeMaxDepth: 256,
},
}, wantErr: false},
Expand All @@ -1033,6 +1031,6 @@ func TestDescriptorToPathNode(t *testing.T) {
println(tt.name)
spew.Dump(PathNodeToInterface(*tt.args.root, tt.args.opts, false))
})

}
}

0 comments on commit 497e7b3

Please sign in to comment.