go-hep.org/x/hep@v0.38.1/groot/rtree/rbasket.go (about)

     1  // Copyright ©2020 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rtree
     6  
     7  import (
     8  	"fmt"
     9  
    10  	"go-hep.org/x/hep/groot/rbytes"
    11  	"go-hep.org/x/hep/groot/riofs"
    12  )
    13  
    14  type rbasket struct {
    15  	id   int    // basket number
    16  	span rspan  // basket entry span
    17  	bk   Basket // current basket
    18  	buf  []byte
    19  }
    20  
    21  func (rbk *rbasket) reset() {
    22  	rbk.id = 0
    23  	rbk.span = rspan{}
    24  }
    25  
    26  func (rbk *rbasket) loadRLeaf(entry int64, leaf rleaf) error {
    27  	var offset int64
    28  	if len(rbk.bk.offsets) == 0 {
    29  		offset = entry*int64(rbk.bk.nevsize) + leaf.Offset() + int64(rbk.bk.key.KeyLen())
    30  	} else {
    31  		offset = int64(rbk.bk.offsets[int(entry)]) + leaf.Offset()
    32  	}
    33  	rbk.bk.rbuf.SetPos(offset)
    34  	return leaf.readFromBuffer(rbk.bk.rbuf)
    35  }
    36  
    37  func (rbk *rbasket) inflate(name string, id int, span rspan, eoff int, f *riofs.File) error {
    38  	var (
    39  		bufsz = span.sz
    40  		seek  = span.pos
    41  	)
    42  
    43  	rbk.id = id
    44  	rbk.span = span
    45  
    46  	var (
    47  		sictx  = f
    48  		err    error
    49  		keylen uint32
    50  	)
    51  
    52  	// handle recovered baskets.
    53  	// the way we attach them to the incoming span (ie: with a pos=0),
    54  	// will enable the bufsz==0 case below.
    55  	if span.bkt != nil {
    56  		rbk.bk = *span.bkt
    57  	}
    58  
    59  	switch {
    60  	case bufsz == 0: // FIXME(sbinet): from trial and error. check this is ok for all cases
    61  
    62  		rbk.bk.key.SetFile(f)
    63  		rbk.buf = rbytes.ResizeU8(rbk.buf, int(rbk.bk.key.ObjLen()))
    64  		_, err = rbk.bk.key.Load(rbk.buf)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		rbk.bk.rbuf = rbk.bk.rbuf.Reset(rbk.buf, nil, keylen, sictx)
    69  
    70  	default:
    71  		rbk.buf = rbytes.ResizeU8(rbk.buf, int(bufsz))
    72  		_, err = f.ReadAt(rbk.buf, seek)
    73  		if err != nil {
    74  			return fmt.Errorf("rtree: could not read basket buffer from file: %w", err)
    75  		}
    76  
    77  		rbk.bk.rbuf = rbk.bk.rbuf.Reset(rbk.buf, nil, 0, sictx)
    78  		err = rbk.bk.UnmarshalROOT(rbk.bk.rbuf)
    79  		if err != nil {
    80  			return fmt.Errorf("rtree: could not unmarshal basket buffer from file: %w", err)
    81  		}
    82  		rbk.bk.key.SetFile(f)
    83  
    84  		rbk.buf = rbytes.ResizeU8(rbk.buf, int(rbk.bk.key.ObjLen()))
    85  		_, err = rbk.bk.key.Load(rbk.buf)
    86  		if err != nil {
    87  			return err
    88  		}
    89  		keylen = uint32(rbk.bk.key.KeyLen())
    90  		rbk.bk.rbuf = rbk.bk.rbuf.Reset(rbk.buf, nil, keylen, sictx)
    91  
    92  		if eoff > 0 {
    93  			last := int64(rbk.bk.last)
    94  			rbk.bk.rbuf.SetPos(last)
    95  			n := int(rbk.bk.rbuf.ReadI32())
    96  			rbk.bk.offsets = rbytes.ResizeI32(rbk.bk.offsets, n)
    97  			rbk.bk.rbuf.ReadArrayI32(rbk.bk.offsets)
    98  			if err := rbk.bk.rbuf.Err(); err != nil {
    99  				return err
   100  			}
   101  		}
   102  	}
   103  
   104  	return nil
   105  }