github.com/matrixorigin/matrixone@v1.2.0/pkg/objectio/reader.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package objectio
    16  
    17  import (
    18  	"context"
    19  	"sync/atomic"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  
    26  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    27  )
    28  
    29  type objectReaderV1 struct {
    30  	Object
    31  	ReaderOptions
    32  	oname     *ObjectName
    33  	metaExt   *Extent
    34  	metaCache atomic.Pointer[ObjectMeta]
    35  }
    36  
    37  func newObjectReaderWithStrV1(name string, fs fileservice.FileService, opts ...ReaderOptionFunc) (*objectReaderV1, error) {
    38  	reader := &objectReaderV1{
    39  		Object: Object{
    40  			name: name,
    41  			fs:   fs,
    42  		},
    43  	}
    44  	for _, f := range opts {
    45  		f(&reader.ReaderOptions)
    46  	}
    47  	return reader, nil
    48  }
    49  
    50  func newObjectReaderV1(
    51  	oname *ObjectName,
    52  	metaExt *Extent,
    53  	fs fileservice.FileService,
    54  	opts ...ReaderOptionFunc,
    55  ) (*objectReaderV1, error) {
    56  	name := oname.String()
    57  	reader := &objectReaderV1{
    58  		Object: Object{
    59  			name: name,
    60  			fs:   fs,
    61  		},
    62  		oname:   oname,
    63  		metaExt: metaExt,
    64  	}
    65  	if len(opts) == 0 {
    66  		reader.metaReadPolicy = fileservice.SkipMemoryCache
    67  		reader.metaReadPolicy |= fileservice.SkipFullFilePreloads
    68  	} else {
    69  		for _, f := range opts {
    70  			f(&reader.ReaderOptions)
    71  		}
    72  	}
    73  	return reader, nil
    74  }
    75  
    76  func (r *objectReaderV1) Init(location Location, fs fileservice.FileService) {
    77  	oName := location.Name()
    78  	extent := location.Extent()
    79  	r.name = oName.String()
    80  	r.oname = &oName
    81  	r.metaExt = &extent
    82  	r.fs = fs
    83  	r.metaCache.Store(nil)
    84  }
    85  
    86  func (r *objectReaderV1) Reset() {
    87  	r.metaExt = nil
    88  	r.oname = nil
    89  	r.metaCache.Store(nil)
    90  }
    91  
    92  func (r *objectReaderV1) GetObject() *Object {
    93  	return &r.Object
    94  }
    95  
    96  func (r *objectReaderV1) GetMetaExtent() *Extent {
    97  	return r.metaExt
    98  }
    99  
   100  func (r *objectReaderV1) GetObjectName() *ObjectName {
   101  	return r.oname
   102  }
   103  
   104  func (r *objectReaderV1) GetName() string {
   105  	return r.name
   106  }
   107  
   108  func (r *objectReaderV1) CacheMetaExtent(ext *Extent) {
   109  	r.metaExt = ext
   110  }
   111  
   112  func (r *objectReaderV1) ReadZM(
   113  	ctx context.Context,
   114  	blk uint16,
   115  	seqnums []uint16,
   116  	m *mpool.MPool,
   117  ) (zms []ZoneMap, err error) {
   118  	var metaHeader ObjectMeta
   119  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   120  		return
   121  	}
   122  	meta, _ := metaHeader.DataMeta()
   123  	blkMeta := meta.GetBlockMeta(uint32(blk))
   124  	zms = blkMeta.ToColumnZoneMaps(seqnums)
   125  	return
   126  }
   127  
   128  func (r *objectReaderV1) ReadMeta(
   129  	ctx context.Context,
   130  	m *mpool.MPool,
   131  ) (meta ObjectMeta, err error) {
   132  	if r.withMetaCache {
   133  		cache := r.metaCache.Load()
   134  		if cache != nil {
   135  			meta = *cache
   136  			return
   137  		}
   138  	}
   139  	if r.oname != nil {
   140  		// read table data block
   141  		if meta, err = LoadObjectMetaByExtent(ctx, r.oname, r.metaExt, false, r.metaReadPolicy, r.fs); err != nil {
   142  			return
   143  		}
   144  	} else {
   145  		// read gc/ckp/etl ... data
   146  		if meta, err = ReadObjectMeta(ctx, r.name, r.metaExt, r.metaReadPolicy, r.fs); err != nil {
   147  			return
   148  		}
   149  	}
   150  	if r.withMetaCache {
   151  		r.metaCache.Store(&meta)
   152  	}
   153  	return
   154  }
   155  
   156  func (r *objectReaderV1) ReadOneBlock(
   157  	ctx context.Context,
   158  	idxs []uint16,
   159  	typs []types.Type,
   160  	blk uint16,
   161  	m *mpool.MPool,
   162  ) (ioVec *fileservice.IOVector, err error) {
   163  	var metaHeader ObjectMeta
   164  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   165  		return
   166  	}
   167  	meta, _ := metaHeader.DataMeta()
   168  	return ReadOneBlockWithMeta(ctx, &meta, r.name, blk, idxs, typs, m, r.fs, constructorFactory, r.dataReadPolicy)
   169  }
   170  
   171  func (r *objectReaderV1) ReadSubBlock(
   172  	ctx context.Context,
   173  	idxs []uint16,
   174  	typs []types.Type,
   175  	blk uint16,
   176  	m *mpool.MPool,
   177  ) (ioVecs []*fileservice.IOVector, err error) {
   178  	var metaHeader ObjectMeta
   179  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   180  		return
   181  	}
   182  	meta, _ := metaHeader.SubMeta(blk)
   183  	ioVecs = make([]*fileservice.IOVector, 0)
   184  	for i := uint32(0); i < meta.BlockCount(); i++ {
   185  		var ioVec *fileservice.IOVector
   186  		ioVec, err = ReadOneBlockWithMeta(ctx, &meta, r.name, meta.BlockHeader().StartID()+uint16(i), idxs, typs, m, r.fs, constructorFactory, fileservice.Policy(0))
   187  		if err != nil {
   188  			return
   189  		}
   190  		ioVecs = append(ioVecs, ioVec)
   191  	}
   192  	return
   193  }
   194  
   195  func (r *objectReaderV1) ReadOneSubBlock(
   196  	ctx context.Context,
   197  	idxs []uint16,
   198  	typs []types.Type,
   199  	dataType uint16,
   200  	blk uint16,
   201  	m *mpool.MPool,
   202  ) (ioVec *fileservice.IOVector, err error) {
   203  	var metaHeader ObjectMeta
   204  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   205  		return
   206  	}
   207  	meta, _ := metaHeader.SubMeta(dataType)
   208  	ioVec, err = ReadOneBlockWithMeta(ctx, &meta, r.name, blk, idxs, typs, m, r.fs, constructorFactory, fileservice.Policy(0))
   209  	if err != nil {
   210  		return
   211  	}
   212  	return
   213  }
   214  
   215  func (r *objectReaderV1) ReadAll(
   216  	ctx context.Context,
   217  	idxs []uint16,
   218  	m *mpool.MPool,
   219  ) (ioVec *fileservice.IOVector, err error) {
   220  	var metaHeader ObjectMeta
   221  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   222  		return
   223  	}
   224  	meta := metaHeader.MustDataMeta()
   225  	return ReadAllBlocksWithMeta(ctx, &meta, r.name, idxs, r.dataReadPolicy, m, r.fs, constructorFactory)
   226  }
   227  
   228  // ReadOneBF read one bloom filter
   229  func (r *objectReaderV1) ReadOneBF(
   230  	ctx context.Context,
   231  	blk uint16,
   232  ) (bf StaticFilter, size uint32, err error) {
   233  	var metaHeader ObjectMeta
   234  	if metaHeader, err = r.ReadMeta(ctx, nil); err != nil {
   235  		return
   236  	}
   237  	meta := metaHeader.MustDataMeta()
   238  	extent := meta.BlockHeader().BFExtent()
   239  	bfs, err := ReadBloomFilter(ctx, r.name, &extent, r.dataReadPolicy, r.fs)
   240  	if err != nil {
   241  		return
   242  	}
   243  	buf := bfs.GetBloomFilter(uint32(blk))
   244  	bf = index.NewEmptyBinaryFuseFilter()
   245  	err = index.DecodeBloomFilter(bf, buf)
   246  	if err != nil {
   247  		return
   248  	}
   249  	size = uint32(len(buf))
   250  	return bf, size, nil
   251  }
   252  
   253  func (r *objectReaderV1) ReadAllBF(
   254  	ctx context.Context,
   255  ) (bfs BloomFilter, size uint32, err error) {
   256  	var metaHeader ObjectMeta
   257  	var buf []byte
   258  	if metaHeader, err = r.ReadMeta(ctx, nil); err != nil {
   259  		return
   260  	}
   261  	meta := metaHeader.MustDataMeta()
   262  	extent := meta.BlockHeader().BFExtent()
   263  	if buf, err = ReadBloomFilter(ctx, r.name, &extent, r.dataReadPolicy, r.fs); err != nil {
   264  		return
   265  	}
   266  	return buf, extent.OriginSize(), nil
   267  }
   268  
   269  func (r *objectReaderV1) ReadExtent(
   270  	ctx context.Context,
   271  	extent Extent,
   272  ) ([]byte, error) {
   273  	v, err := ReadExtent(
   274  		ctx,
   275  		r.name,
   276  		&extent,
   277  		r.metaReadPolicy,
   278  		r.fs,
   279  		constructorFactory)
   280  	if err != nil {
   281  		return nil, err
   282  	}
   283  
   284  	var obj any
   285  	obj, err = Decode(v)
   286  	if err != nil {
   287  		return nil, err
   288  	}
   289  
   290  	return obj.([]byte), nil
   291  }
   292  
   293  func (r *objectReaderV1) ReadMultiBlocks(
   294  	ctx context.Context,
   295  	opts map[uint16]*ReadBlockOptions,
   296  	m *mpool.MPool,
   297  ) (ioVec *fileservice.IOVector, err error) {
   298  	var objectMeta ObjectMeta
   299  	if objectMeta, err = r.ReadMeta(ctx, m); err != nil {
   300  		return
   301  	}
   302  	return ReadMultiBlocksWithMeta(
   303  		ctx,
   304  		r.name,
   305  		objectMeta,
   306  		opts,
   307  		r.fs,
   308  		constructorFactory)
   309  }
   310  
   311  func (r *objectReaderV1) ReadMultiSubBlocks(
   312  	ctx context.Context,
   313  	opts map[uint16]*ReadBlockOptions,
   314  	m *mpool.MPool,
   315  ) (ioVec *fileservice.IOVector, err error) {
   316  	var metaHeader ObjectMeta
   317  	if metaHeader, err = r.ReadMeta(ctx, m); err != nil {
   318  		return
   319  	}
   320  	ioVec = &fileservice.IOVector{
   321  		FilePath: r.name,
   322  		Entries:  make([]fileservice.IOEntry, 0),
   323  	}
   324  	for _, opt := range opts {
   325  		meta, _ := metaHeader.SubMeta(opt.DataType)
   326  		for seqnum := range opt.Idxes {
   327  			blkmeta := meta.GetBlockMeta(uint32(opt.Id))
   328  			if seqnum > blkmeta.GetMaxSeqnum() || blkmeta.ColumnMeta(seqnum).DataType() == 0 {
   329  				// prefetch, do not generate
   330  				continue
   331  			}
   332  			col := blkmeta.ColumnMeta(seqnum)
   333  			ioVec.Entries = append(ioVec.Entries, fileservice.IOEntry{
   334  				Offset: int64(col.Location().Offset()),
   335  				Size:   int64(col.Location().Length()),
   336  
   337  				ToCacheData: constructorFactory(int64(col.Location().OriginSize()), col.Location().Alg()),
   338  			})
   339  		}
   340  	}
   341  
   342  	err = r.fs.Read(ctx, ioVec)
   343  	return
   344  }
   345  
   346  func (r *objectReaderV1) ReadAllMeta(
   347  	ctx context.Context,
   348  	m *mpool.MPool,
   349  ) (ObjectMeta, error) {
   350  	if r.metaExt == nil {
   351  		header, err := r.ReadHeader(ctx, m)
   352  		if err != nil {
   353  			return nil, err
   354  		}
   355  		ext := header.Extent()
   356  		r.CacheMetaExtent(&ext)
   357  	}
   358  	return r.ReadMeta(ctx, m)
   359  }
   360  
   361  func (r *objectReaderV1) ReadHeader(ctx context.Context, m *mpool.MPool) (h Header, err error) {
   362  	ext := NewExtent(0, 0, HeaderSize, HeaderSize)
   363  	v, err := ReadExtent(ctx, r.name, &ext, r.metaReadPolicy, r.fs, constructorFactory)
   364  	if err != nil {
   365  		return
   366  	}
   367  	h = Header(v)
   368  	return
   369  }
   370  
   371  type ReaderOptions struct {
   372  	// metaReadPolicy true means NOT cache IOVector in FileService's cache
   373  	metaReadPolicy fileservice.Policy
   374  	dataReadPolicy fileservice.Policy
   375  	// withMetaCache true means cache objectDataMetaV1 in the Reader
   376  	// Note: if withMetaCache is true, cleanup is needed
   377  	withMetaCache bool
   378  }
   379  
   380  type ReaderOptionFunc func(opt *ReaderOptions)
   381  
   382  func WithDataCachePolicyOption(noLRUCache fileservice.Policy) ReaderOptionFunc {
   383  	return ReaderOptionFunc(func(opt *ReaderOptions) {
   384  		opt.dataReadPolicy = noLRUCache
   385  	})
   386  }
   387  
   388  func WithMetaCachePolicyOption(noLRUCache fileservice.Policy) ReaderOptionFunc {
   389  	return ReaderOptionFunc(func(opt *ReaderOptions) {
   390  		opt.metaReadPolicy = noLRUCache
   391  	})
   392  }