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 }