github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/node.go (about)

     1  package generic
     2  
     3  import (
     4  	"fmt"
     5  	"unsafe"
     6  
     7  	"github.com/cloudwego/dynamicgo/internal/rt"
     8  	"github.com/cloudwego/dynamicgo/meta"
     9  	"github.com/cloudwego/dynamicgo/proto"
    10  	"github.com/cloudwego/dynamicgo/proto/binary"
    11  	"github.com/cloudwego/dynamicgo/proto/protowire"
    12  )
    13  
    14  type Node struct {
    15  	t    proto.Type
    16  	et   proto.Type
    17  	kt   proto.Type
    18  	v    unsafe.Pointer
    19  	l    int
    20  	size int // only for MAP/LIST element counts
    21  }
    22  
    23  // Fork forks the node to a new node, copy underlying data as well
    24  func (self Node) Fork() Node {
    25  	ret := self
    26  	buf := make([]byte, self.l, self.l)
    27  	copy(buf, rt.BytesFrom(self.v, self.l, self.l))
    28  	ret.v = rt.GetBytePtr(buf)
    29  	return ret
    30  }
    31  
    32  // Type returns the proto type of the node
    33  func (self Node) Type() proto.Type {
    34  	return self.t
    35  }
    36  
    37  // ElemType returns the thrift type of a LIST/MAP node's element
    38  func (self Node) ElemType() proto.Type {
    39  	return self.et
    40  }
    41  
    42  // KeyType returns the thrift type of a MAP node's key
    43  func (self Node) KeyType() proto.Type {
    44  	return self.kt
    45  }
    46  
    47  // slice returns a new node which is a slice of a simple node
    48  func (self Node) slice(s int, e int, t proto.Type) Node {
    49  	ret := Node{
    50  		t: t,
    51  		l: (e - s),
    52  		v: rt.AddPtr(self.v, uintptr(s)),
    53  	}
    54  	return ret
    55  }
    56  
    57  // sliceComplex returns a new node which is a slice of a Complex(can deal with all the type) node
    58  func (self Node) sliceComplex(s int, e int, t proto.Type, kt proto.Type, et proto.Type, size int) Node {
    59  	ret := Node{
    60  		t: t,
    61  		l: (e - s),
    62  		v: rt.AddPtr(self.v, uintptr(s)),
    63  	}
    64  	if t == proto.LIST {
    65  		ret.et = et
    66  		ret.size = size
    67  	} else if t == proto.MAP {
    68  		ret.kt = kt
    69  		ret.et = et
    70  		ret.size = size
    71  	}
    72  	return ret
    73  }
    74  
    75  func (self Node) sliceNodeWithDesc(s int, e int, desc *proto.TypeDescriptor) Node {
    76  	t := desc.Type()
    77  	ret := Node{
    78  		t: t,
    79  		l: (e - s),
    80  		v: rt.AddPtr(self.v, uintptr(s)),
    81  	}
    82  	if t == proto.LIST {
    83  		ret.et = desc.Elem().Type()
    84  	} else if t == proto.MAP {
    85  		ret.kt = desc.Key().Type()
    86  		ret.et = desc.Elem().Type()
    87  	}
    88  	return ret
    89  }
    90  
    91  func (self Node) offset() unsafe.Pointer {
    92  	return rt.AddPtr(self.v, uintptr(self.l))
    93  }
    94  
    95  func (self *Node) SetElemType(et proto.Type) {
    96  	self.et = et
    97  }
    98  
    99  func (self *Node) SetKeyType(kt proto.Type) {
   100  	self.kt = kt
   101  }
   102  
   103  func (self *Node) replace(o Node, n Node) error {
   104  	// mush ensure target value is same type as source value
   105  	if o.t != n.t {
   106  		return wrapError(meta.ErrDismatchType, fmt.Sprintf("type mismatch: %s != %s", o.t, n.t), nil)
   107  	}
   108  	// export target node to bytes
   109  	pat := n.raw()
   110  
   111  	// divide self's buffer into three slices:
   112  	// 1. self's slice before the target node
   113  	// 2. target node's slice
   114  	// 3. self's slice after the target node
   115  	s1 := rt.AddPtr(o.v, uintptr(o.l))
   116  	l0 := int(uintptr(o.v) - uintptr(self.v))
   117  	l1 := len(pat)
   118  	l2 := int(uintptr(self.v) + uintptr(self.l) - uintptr(s1))
   119  
   120  	// copy three slices into new buffer
   121  	buf := make([]byte, l0+l1+l2)
   122  	copy(buf[:l0], rt.BytesFrom(self.v, l0, l0))
   123  	copy(buf[l0:l0+l1], pat)
   124  	copy(buf[l0+l1:l0+l1+l2], rt.BytesFrom(s1, l2, l2))
   125  
   126  	// replace self's entire buffer
   127  	self.v = rt.GetBytePtr(buf)
   128  	self.l = int(len(buf))
   129  	return nil
   130  }
   131  
   132  // have problem in deal with byteLength
   133  func (o *Node) setNotFound(path Path, n *Node, desc *proto.TypeDescriptor) error {
   134  	switch o.kt {
   135  	case proto.MESSAGE:
   136  		tag := path.ToRaw(n.t)
   137  		src := n.raw()
   138  		buf := make([]byte, 0, len(tag)+len(src))
   139  		buf = append(buf, tag...)
   140  		buf = append(buf, src...)
   141  		n.l = len(buf)
   142  		n.v = rt.GetBytePtr(buf)
   143  	case proto.LIST:
   144  		// unpacked need write tag, packed needn't
   145  		if desc.IsPacked() == false {
   146  			fdNum := desc.BaseId()
   147  			tag := protowire.AppendVarint(nil, uint64(fdNum)<<3|uint64(proto.BytesType))
   148  			src := n.raw()
   149  			buf := make([]byte, 0, len(tag)+len(src))
   150  			buf = append(buf, tag...)
   151  			buf = append(buf, src...)
   152  			n.l = len(buf)
   153  			n.v = rt.GetBytePtr(buf)
   154  		}
   155  	case proto.MAP:
   156  		// pair tag
   157  		fdNum := desc.BaseId()
   158  		pairTag := protowire.AppendVarint(nil, uint64(fdNum)<<3|uint64(proto.BytesType))
   159  		buf := path.ToRaw(n.t) // keytag + key
   160  		valueWireType := desc.Elem().WireType()
   161  		valueTag := uint64(1)<<3 | uint64(valueWireType)
   162  		buf = protowire.BinaryEncoder{}.EncodeUint64(buf, valueTag)                  // + value tag
   163  		src := n.raw()                                                               // + value
   164  		buf = append(buf, src...)                                                    // key + value
   165  		pairbuf := protowire.BinaryEncoder{}.EncodeUint64(pairTag, uint64(len(buf))) // + pairlen
   166  		pairbuf = append(pairbuf, buf...)                                            // pair tag + pairlen + key + value
   167  		n.l = len(pairbuf)
   168  		n.v = rt.GetBytePtr(pairbuf)
   169  	default:
   170  		return wrapError(meta.ErrDismatchType, "simple type node shouldn't have child", nil)
   171  	}
   172  	o.t = n.t
   173  	o.l = 0
   174  	return nil
   175  }
   176  
   177  func (self *Node) replaceMany(ps *pnSlice) error {
   178  	var buf []byte
   179  	// Sort pathes by original value address
   180  	ps.Sort()
   181  
   182  	// sequentially set new values into buffer according to sorted pathes
   183  	buf = make([]byte, 0, self.l)
   184  	last := self.v
   185  	for i := 0; i < len(ps.a); i++ {
   186  		lastLen := rt.PtrOffset(ps.a[i].Node.v, last)
   187  		// copy last slice from original buffer
   188  		buf = append(buf, rt.BytesFrom(last, lastLen, lastLen)...)
   189  		// copy new value's buffer into buffer
   190  		buf = append(buf, ps.b[i].Node.raw()...)
   191  		// update last index
   192  		last = ps.a[i].offset()
   193  	}
   194  	if tail := self.offset(); uintptr(last) < uintptr(tail) {
   195  		// copy last slice from original buffer
   196  		buf = append(buf, rt.BytesFrom(last, rt.PtrOffset(tail, last), rt.PtrOffset(tail, last))...)
   197  	}
   198  
   199  	self.v = rt.GetBytePtr(buf)
   200  	self.l = int(len(buf))
   201  	return nil
   202  }
   203  
   204  // NewNode method: creates a new node from a byte slice
   205  func NewNode(t proto.Type, src []byte) Node {
   206  	ret := Node{
   207  		t: t,
   208  		l: (len(src)),
   209  		v: rt.GetBytePtr(src),
   210  	}
   211  	return ret
   212  }
   213  
   214  func NewNodeBool(val bool) Node {
   215  	buf := make([]byte, 0, 1)
   216  	buf = protowire.BinaryEncoder{}.EncodeBool(buf, val)
   217  	return NewNode(proto.BOOL, buf)
   218  }
   219  
   220  func NewNodeByte(val byte) Node {
   221  	buf := make([]byte, 0, 1)
   222  	buf = protowire.BinaryEncoder{}.EncodeByte(buf, val)
   223  	return NewNode(proto.BYTE, buf)
   224  }
   225  
   226  func NewNodeEnum(val int32) Node {
   227  	buf := make([]byte, 0, 4)
   228  	buf = protowire.BinaryEncoder{}.EncodeEnum(buf, val)
   229  	return NewNode(proto.ENUM, buf)
   230  }
   231  
   232  func NewNodeInt32(val int32) Node {
   233  	buf := make([]byte, 0, 4)
   234  	buf = protowire.BinaryEncoder{}.EncodeInt32(buf, val)
   235  	return NewNode(proto.INT32, buf)
   236  }
   237  
   238  func NewNodeSint32(val int32) Node {
   239  	buf := make([]byte, 0, 4)
   240  	buf = protowire.BinaryEncoder{}.EncodeSint32(buf, val)
   241  	return NewNode(proto.SINT32, buf)
   242  }
   243  
   244  func NewNodeUint32(val uint32) Node {
   245  	buf := make([]byte, 0, 4)
   246  	buf = protowire.BinaryEncoder{}.EncodeUint32(buf, val)
   247  	return NewNode(proto.UINT32, buf)
   248  }
   249  
   250  func NewNodeFixed32(val uint32) Node {
   251  	buf := make([]byte, 0, 4)
   252  	buf = protowire.BinaryEncoder{}.EncodeFixed32(buf, val)
   253  	return NewNode(proto.FIX32, buf)
   254  }
   255  
   256  func NewNodeSfixed32(val int32) Node {
   257  	buf := make([]byte, 0, 4)
   258  	buf = protowire.BinaryEncoder{}.EncodeSfixed32(buf, val)
   259  	return NewNode(proto.SFIX32, buf)
   260  }
   261  
   262  func NewNodeInt64(val int64) Node {
   263  	buf := make([]byte, 0, 8)
   264  	buf = protowire.BinaryEncoder{}.EncodeInt64(buf, val)
   265  	return NewNode(proto.INT64, buf)
   266  }
   267  
   268  func NewNodeSint64(val int64) Node {
   269  	buf := make([]byte, 0, 8)
   270  	buf = protowire.BinaryEncoder{}.EncodeSint64(buf, val)
   271  	return NewNode(proto.SINT64, buf)
   272  }
   273  
   274  func NewNodeUint64(val uint64) Node {
   275  	buf := make([]byte, 0, 8)
   276  	buf = protowire.BinaryEncoder{}.EncodeUint64(buf, val)
   277  	return NewNode(proto.UINT64, buf)
   278  }
   279  
   280  func NewNodeFixed64(val uint64) Node {
   281  	buf := make([]byte, 0, 8)
   282  	buf = protowire.BinaryEncoder{}.EncodeFixed64(buf, val)
   283  	return NewNode(proto.FIX64, buf)
   284  }
   285  
   286  func NewNodeSfixed64(val int64) Node {
   287  	buf := make([]byte, 0, 8)
   288  	buf = protowire.BinaryEncoder{}.EncodeSfixed64(buf, val)
   289  	return NewNode(proto.SFIX64, buf)
   290  }
   291  
   292  func NewNodeFloat(val float32) Node {
   293  	buf := make([]byte, 0, 4)
   294  	buf = protowire.BinaryEncoder{}.EncodeFloat32(buf, val)
   295  	return NewNode(proto.FLOAT, buf)
   296  }
   297  
   298  func NewNodeDouble(val float64) Node {
   299  	buf := make([]byte, 0, 8)
   300  	buf = protowire.BinaryEncoder{}.EncodeDouble(buf, val)
   301  	return NewNode(proto.DOUBLE, buf)
   302  }
   303  
   304  func NewNodeString(val string) Node {
   305  	buf := make([]byte, 0, len(val)+4)
   306  	buf = protowire.BinaryEncoder{}.EncodeString(buf, val)
   307  	return NewNode(proto.STRING, buf)
   308  }
   309  
   310  func NewNodeBytes(val []byte) Node {
   311  	buf := make([]byte, 0, len(val)+4)
   312  	buf = protowire.BinaryEncoder{}.EncodeBytes(buf, val)
   313  	return NewNode(proto.BYTE, buf)
   314  }
   315  
   316  // NewComplexNode can deal with all the types, only if the src is a valid byte slice
   317  func NewComplexNode(t proto.Type, et proto.Type, kt proto.Type, src []byte) (ret Node) {
   318  	if !t.Valid() {
   319  		panic("invalid node type")
   320  	}
   321  	ret = Node{
   322  		t: t,
   323  		l: (len(src)),
   324  		v: rt.GetBytePtr(src),
   325  	}
   326  
   327  	switch t {
   328  	case proto.LIST:
   329  		if !et.Valid() {
   330  			panic("invalid element type")
   331  		}
   332  		ret.et = et
   333  	case proto.MAP:
   334  		if !et.Valid() {
   335  			panic("invalid element type")
   336  		}
   337  		if !kt.Valid() {
   338  			panic("invalid key type")
   339  		}
   340  		ret.et = et
   341  		ret.kt = kt
   342  	}
   343  
   344  	return
   345  }
   346  
   347  // returns all the children of a node, when recurse is false, it switch to lazyload mode, only direct children are returned
   348  func (self Node) Children(out *[]PathNode, recurse bool, opts *Options, desc *proto.TypeDescriptor) (err error) {
   349  	if self.Error() != "" {
   350  		return self
   351  	}
   352  
   353  	if out == nil {
   354  		panic("out is nil")
   355  	}
   356  	// NOTICE: since we only use out for memory reuse, we always reset it to zero.
   357  	p := binary.BinaryProtocol{
   358  		Buf: self.raw(),
   359  	}
   360  
   361  	tree := PathNode{
   362  		Node: self,
   363  		Next: (*out)[:0], // NOTICE: we reset it to zero.
   364  	}
   365  	err = tree.scanChildren(&p, recurse, opts, desc, len(p.Buf))
   366  	if err == nil {
   367  		*out = tree.Next
   368  	}
   369  	return err
   370  }
   371  
   372  // Get idx element of a LIST node
   373  func (self Node) Index(idx int) (v Node) {
   374  	if err := self.should("Index", proto.LIST); err != "" {
   375  		return errNode(meta.ErrUnsupportedType, err, nil)
   376  	}
   377  
   378  	var s, e int
   379  	it := self.iterElems()
   380  	if it.Err != nil {
   381  		return errNode(meta.ErrRead, "", it.Err)
   382  	}
   383  	isPacked := it.IsPacked()
   384  
   385  	// size = 0 maybe list node is in lazyload mode, need to check idx with it.k
   386  	if it.size > 0 && idx >= it.size {
   387  		return errNode(meta.ErrInvalidParam, fmt.Sprintf("index %d exceeds list/set bound", idx), nil)
   388  	}
   389  
   390  	// read packed list tag and bytelen
   391  	if isPacked {
   392  		if _, _, _, err := it.p.ConsumeTag(); err != nil {
   393  			return errNode(meta.ErrRead, "", err)
   394  		}
   395  		if _, err := it.p.ReadLength(); err != nil {
   396  			return errNode(meta.ErrRead, "", err)
   397  		}
   398  	}
   399  
   400  	for j := 0; it.HasNext() && j < idx; j++ {
   401  		it.Next(UseNativeSkipForGet)
   402  	}
   403  
   404  	if it.Err != nil {
   405  		return errNode(meta.ErrRead, "", it.Err)
   406  	}
   407  
   408  	// when lazy load, size = 0, use it.k which is counted after it.Next() to check valid idx
   409  	if idx > it.k {
   410  		return errNode(meta.ErrInvalidParam, fmt.Sprintf("index '%d' is out of range", idx), nil)
   411  	}
   412  
   413  	s, e = it.Next(UseNativeSkipForGet)
   414  	v = self.slice(s, e, self.et)
   415  	return v
   416  }
   417  
   418  // Get string key of a MAP node
   419  func (self Node) GetByStr(key string) (v Node) {
   420  	if err := self.should("Get", proto.MAP); err != "" {
   421  		return errNode(meta.ErrUnsupportedType, err, nil)
   422  	}
   423  
   424  	if self.kt != proto.STRING {
   425  		return errNode(meta.ErrUnsupportedType, "key type is not string", nil)
   426  	}
   427  
   428  	it := self.iterPairs()
   429  	if it.Err != nil {
   430  		return errNode(meta.ErrRead, "", it.Err)
   431  	}
   432  
   433  	for it.HasNext() {
   434  		_, s, ss, e := it.NextStr(UseNativeSkipForGet)
   435  		if it.Err != nil {
   436  			v = errNode(meta.ErrRead, "", it.Err)
   437  			goto ret
   438  		}
   439  
   440  		if s == key {
   441  			v = self.slice(ss, e, self.et)
   442  			goto ret
   443  		}
   444  	}
   445  	v = errNode(meta.ErrNotFound, fmt.Sprintf("key '%s' is not found in this value", key), errNotFound)
   446  ret:
   447  	return
   448  }
   449  
   450  // Get int key of a MAP node
   451  func (self Node) GetByInt(key int) (v Node) {
   452  	if err := self.should("Get", proto.MAP); err != "" {
   453  		return errNode(meta.ErrUnsupportedType, err, nil)
   454  	}
   455  
   456  	if !self.kt.IsInt() {
   457  		return errNode(meta.ErrUnsupportedType, "key type is not int", nil)
   458  	}
   459  
   460  	it := self.iterPairs()
   461  	if it.Err != nil {
   462  		return errNode(meta.ErrRead, "", it.Err)
   463  	}
   464  
   465  	for it.HasNext() {
   466  		_, i, ss, e := it.NextInt(UseNativeSkipForGet)
   467  		if it.Err != nil {
   468  			v = errNode(meta.ErrRead, "", it.Err)
   469  			goto ret
   470  		}
   471  		if i == key {
   472  			v = self.slice(ss, e, self.et)
   473  			goto ret
   474  		}
   475  	}
   476  	v = errNode(meta.ErrNotFound, fmt.Sprintf("key '%d' is not found in this value", key), nil)
   477  ret:
   478  	return
   479  }
   480  
   481  func (self Node) Field(id proto.FieldNumber, rootLayer bool, msgDesc *proto.MessageDescriptor) (v Node, f *proto.FieldDescriptor) {
   482  	if err := self.should("Field", proto.MESSAGE); err != "" {
   483  		return errNode(meta.ErrUnsupportedType, err, nil), nil
   484  	}
   485  
   486  	fd := msgDesc.ByNumber(id)
   487  
   488  	if fd == nil {
   489  		return errNode(meta.ErrUnknownField, fmt.Sprintf("field '%d' is not defined in IDL", id), nil), nil
   490  	}
   491  
   492  	it := self.iterFields()
   493  
   494  	if it.Err != nil {
   495  		return errNode(meta.ErrRead, "", it.Err), nil
   496  	}
   497  
   498  	if !rootLayer {
   499  		if _, err := it.p.ReadLength(); err != nil {
   500  			return errNode(meta.ErrRead, "", err), nil
   501  		}
   502  
   503  		if it.Err != nil {
   504  			return errNode(meta.ErrRead, "", it.Err), nil
   505  		}
   506  	}
   507  
   508  	for it.HasNext() {
   509  		i, wt, s, e, tagPos := it.Next(UseNativeSkipForGet)
   510  		if i == fd.Number() {
   511  			typDesc := fd.Type()
   512  			if typDesc.IsMap() || typDesc.IsList() {
   513  				it.p.Read = tagPos
   514  				if _, err := it.p.SkipAllElements(i, typDesc.IsPacked()); err != nil {
   515  					return errNode(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err), nil
   516  				}
   517  				s = tagPos
   518  				e = it.p.Read
   519  
   520  				v = self.sliceNodeWithDesc(s, e, typDesc)
   521  				goto ret
   522  			}
   523  
   524  			t := proto.Kind2Wire[fd.Kind()]
   525  			if wt != t {
   526  				v = errNode(meta.ErrDismatchType, fmt.Sprintf("field '%s' expects type %s, buf got type %s", fd.Name(), t, wt), nil)
   527  				goto ret
   528  			}
   529  			v = self.sliceNodeWithDesc(s, e, typDesc)
   530  			goto ret
   531  		} else if it.Err != nil {
   532  			v = errNode(meta.ErrRead, "", it.Err)
   533  			goto ret
   534  		}
   535  	}
   536  
   537  	v = errNode(meta.ErrNotFound, fmt.Sprintf("field '%d' is not found in this value", id), errNotFound)
   538  ret:
   539  	return v, fd
   540  }
   541  
   542  func (self Node) Fields(ids []PathNode, rootLayer bool, msgDesc *proto.MessageDescriptor, opts *Options) error {
   543  	if err := self.should("Fields", proto.MESSAGE); err != "" {
   544  		return errNode(meta.ErrUnsupportedType, err, nil)
   545  	}
   546  
   547  	if len(ids) == 0 {
   548  		return nil
   549  	}
   550  
   551  	if opts.ClearDirtyValues {
   552  		for i := range ids {
   553  			ids[i].Node = Node{}
   554  		}
   555  	}
   556  
   557  	it := self.iterFields()
   558  	if it.Err != nil {
   559  		return errNode(meta.ErrRead, "", it.Err)
   560  	}
   561  
   562  
   563  
   564  	if !rootLayer {
   565  		if _, err := it.p.ReadLength(); err != nil {
   566  			return errNode(meta.ErrRead, "", err)
   567  		}
   568  
   569  		if it.Err != nil {
   570  			return errNode(meta.ErrRead, "", it.Err)
   571  		}
   572  	}
   573  
   574  	need := len(ids)
   575  	for count := 0; it.HasNext() && count < need; {
   576  		var p *PathNode
   577  		i, _, s, e, tagPos := it.Next(UseNativeSkipForGet)
   578  		if it.Err != nil {
   579  			return errNode(meta.ErrRead, "", it.Err)
   580  		}
   581  		f := msgDesc.ByNumber(i)
   582  		typDesc := f.Type()
   583  		if typDesc.IsMap() || typDesc.IsList() {
   584  			it.p.Read = tagPos
   585  			if _, err := it.p.SkipAllElements(i, typDesc.IsPacked()); err != nil {
   586  				return errNode(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err)
   587  			}
   588  			s = tagPos
   589  			e = it.p.Read
   590  		}
   591  
   592  		v := self.sliceNodeWithDesc(s, e, typDesc)
   593  
   594  		//TODO: use bitmap to avoid repeatedly scan
   595  		for j, id := range ids {
   596  			if id.Path.t == PathFieldId && id.Path.id() == i {
   597  				p = &ids[j]
   598  				count += 1
   599  				break
   600  			}
   601  		}
   602  
   603  		if p != nil {
   604  			p.Node = v
   605  		}
   606  	}
   607  
   608  	return nil
   609  }
   610  
   611  func (self Node) Indexes(ins []PathNode, opts *Options) error {
   612  	if err := self.should("Indexes", proto.LIST); err != "" {
   613  		return errNode(meta.ErrUnsupportedType, err, nil)
   614  	}
   615  
   616  	if len(ins) == 0 {
   617  		return nil
   618  	}
   619  
   620  	if opts.ClearDirtyValues {
   621  		for i := range ins {
   622  			ins[i].Node = Node{}
   623  		}
   624  	}
   625  
   626  	it := self.iterElems()
   627  	if it.Err != nil {
   628  		return errNode(meta.ErrRead, "", it.Err)
   629  	}
   630  
   631  	need := len(ins)
   632  	IsPacked := it.IsPacked()
   633  
   634  	// read packed list tag and bytelen
   635  	if IsPacked {
   636  		if _, _, _, err := it.p.ConsumeTag(); err != nil {
   637  			return errNode(meta.ErrRead, "", err)
   638  		}
   639  		if _, err := it.p.ReadLength(); err != nil {
   640  			return errNode(meta.ErrRead, "", err)
   641  		}
   642  	}
   643  
   644  	for count, i := 0, 0; it.HasNext() && count < need; i++ {
   645  		s, e := it.Next(UseNativeSkipForGet)
   646  		if it.Err != nil {
   647  			return errNode(meta.ErrRead, "", it.Err)
   648  		}
   649  
   650  		// check if the index is in the pathes
   651  		var p *PathNode
   652  		for j, id := range ins {
   653  			if id.Path.t != PathIndex {
   654  				continue
   655  			}
   656  			k := id.Path.int()
   657  			if k >= it.size {
   658  				continue
   659  			}
   660  			if k == i {
   661  				p = &ins[j]
   662  				count += 1
   663  				break
   664  			}
   665  		}
   666  		// PathNode is found
   667  		if p != nil {
   668  			p.Node = self.slice(s, e, self.et)
   669  		}
   670  	}
   671  	return nil
   672  }
   673  
   674  func (self Node) Gets(keys []PathNode, opts *Options) error {
   675  	if err := self.should("Gets", proto.MAP); err != "" {
   676  		return errNode(meta.ErrUnsupportedType, err, nil)
   677  	}
   678  
   679  	if len(keys) == 0 {
   680  		return nil
   681  	}
   682  
   683  	if opts.ClearDirtyValues {
   684  		for i := range keys {
   685  			keys[i].Node = Node{}
   686  		}
   687  	}
   688  
   689  	et := self.et
   690  	it := self.iterPairs()
   691  	if it.Err != nil {
   692  		return errNode(meta.ErrRead, "", it.Err)
   693  	}
   694  
   695  	need := len(keys)
   696  	for count := 0; it.HasNext() && count < need; {
   697  		for j, id := range keys {
   698  			if id.Path.Type() == PathStrKey {
   699  				exp := id.Path.str()
   700  				_, key, s, e := it.NextStr(UseNativeSkipForGet)
   701  				if it.Err != nil {
   702  					return errNode(meta.ErrRead, "", it.Err)
   703  				}
   704  				if key == exp {
   705  					keys[j].Node = self.slice(s, e, et)
   706  					count += 1
   707  					break
   708  				}
   709  			} else if id.Path.Type() == PathIntKey {
   710  				exp := id.Path.int()
   711  				_, key, s, e := it.NextInt(UseNativeSkipForGet)
   712  				if it.Err != nil {
   713  					return errNode(meta.ErrRead, "", it.Err)
   714  				}
   715  				if key == exp {
   716  					keys[j].Node = self.slice(s, e, et)
   717  					count += 1
   718  					break
   719  				}
   720  			}
   721  		}
   722  	}
   723  	return nil
   724  }