github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/reader/microreader/microreader.go (about)

     1  /*
     2  Copyright 2023.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package microreader
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"os"
    23  
    24  	"github.com/siglens/siglens/pkg/blob"
    25  	"github.com/siglens/siglens/pkg/segment/structs"
    26  	"github.com/siglens/siglens/pkg/segment/utils"
    27  	toputils "github.com/siglens/siglens/pkg/utils"
    28  
    29  	log "github.com/sirupsen/logrus"
    30  )
    31  
    32  const SECONDS_REREAD_META = 10
    33  
    34  func ReadBlockSummaries(fileName string, rbuf []byte) ([]*structs.BlockSummary,
    35  	map[uint16]*structs.BlockMetadataHolder, []byte, error) {
    36  
    37  	blockSummaries := make([]*structs.BlockSummary, 0)
    38  	allBmh := make(map[uint16]*structs.BlockMetadataHolder)
    39  	err := blob.DownloadSegmentBlob(fileName, false)
    40  	if err != nil {
    41  		log.Errorf("ReadBlockSummaries: Error downloading block summary file at %s, err: %v", fileName, err)
    42  		return blockSummaries, allBmh, rbuf, err
    43  	}
    44  
    45  	finfo, err := os.Stat(fileName)
    46  	if err != nil {
    47  		log.Errorf("ReadBlockSummaries: error when trying to stat file=%+v. Error=%+v", fileName, err)
    48  		return blockSummaries, allBmh, rbuf, err
    49  	}
    50  
    51  	fileSize := finfo.Size()
    52  	sizeToAdd := fileSize - int64(len(rbuf))
    53  	if sizeToAdd > 0 {
    54  		newArr := make([]byte, sizeToAdd)
    55  		rbuf = append(rbuf, newArr...)
    56  	}
    57  
    58  	fd, err := os.OpenFile(fileName, os.O_RDONLY, 0644)
    59  	if err != nil {
    60  		log.Infof("ReadBlockSummaries: failed to open fileName: %v  Error: %v.",
    61  			fileName, err)
    62  		return blockSummaries, allBmh, rbuf, err
    63  	}
    64  	defer fd.Close()
    65  
    66  	_, err = fd.ReadAt(rbuf[:fileSize], 0)
    67  	if err != nil {
    68  		log.Errorf("ReadBlockSummaries: Error reading bsu file: %v, err: %v", fileName, err)
    69  		return blockSummaries, allBmh, rbuf, err
    70  	}
    71  
    72  	offset := int64(0)
    73  
    74  	for offset < fileSize {
    75  
    76  		// todo kunal do we need blksumlen ?
    77  		offset += 4 // for blkSumLen
    78  
    79  		// read blknum
    80  		blkNum := toputils.BytesToUint16LittleEndian(rbuf[offset:])
    81  		offset += 2
    82  
    83  		// read highTs
    84  		highTs := toputils.BytesToUint64LittleEndian(rbuf[offset:])
    85  		offset += 8
    86  
    87  		// read lowTs
    88  		lowTs := toputils.BytesToUint64LittleEndian(rbuf[offset:])
    89  		offset += 8
    90  
    91  		// read recCount
    92  		recCount := toputils.BytesToUint16LittleEndian(rbuf[offset:])
    93  		offset += 2
    94  
    95  		// read numCols
    96  		numCols := toputils.BytesToUint16LittleEndian(rbuf[offset:])
    97  		offset += 2
    98  		bmh := &structs.BlockMetadataHolder{
    99  			BlkNum:            blkNum,
   100  			ColumnBlockOffset: make(map[string]int64, numCols),
   101  			ColumnBlockLen:    make(map[string]uint32, numCols),
   102  		}
   103  
   104  		for i := uint16(0); i < numCols; i++ {
   105  			cnamelen := toputils.BytesToUint16LittleEndian(rbuf[offset:])
   106  			offset += 2
   107  			cname := string(rbuf[offset : offset+int64(cnamelen)])
   108  			offset += int64(cnamelen)
   109  			blkOff := toputils.BytesToInt64LittleEndian(rbuf[offset:])
   110  			offset += 8
   111  			blkLen := toputils.BytesToUint32LittleEndian(rbuf[offset:])
   112  			offset += 4
   113  			bmh.ColumnBlockOffset[cname] = blkOff
   114  			bmh.ColumnBlockLen[cname] = blkLen
   115  		}
   116  		allBmh[blkNum] = bmh
   117  
   118  		blkSumm := &structs.BlockSummary{HighTs: highTs,
   119  			LowTs:    lowTs,
   120  			RecCount: recCount}
   121  
   122  		blockSummaries = append(blockSummaries, blkSumm)
   123  	}
   124  
   125  	return blockSummaries, allBmh, rbuf, nil
   126  }
   127  
   128  func ReadSegMeta(fname string) (*structs.SegMeta, error) {
   129  
   130  	var sm structs.SegMeta
   131  	rdata, err := os.ReadFile(fname)
   132  	if err != nil {
   133  		log.Errorf("ReadSegMeta: error reading file = %v, err= %v", fname, err)
   134  		return nil, err
   135  
   136  	}
   137  
   138  	err = json.Unmarshal(rdata, &sm)
   139  	if err != nil {
   140  		log.Errorf("Cannot unmarshal data = %v, err= %v", string(rdata), err)
   141  		return nil, err
   142  	}
   143  	return &sm, nil
   144  }
   145  
   146  func ReadMetricsBlockSummaries(fileName string) ([]*structs.MBlockSummary, error) {
   147  	mBlockSummaries := make([]*structs.MBlockSummary, 0)
   148  	err := blob.DownloadSegmentBlob(fileName, false)
   149  	if err != nil {
   150  		log.Errorf("ReadMetricsBlockSummaries: Error downloading metrics block summary file at %s, err: %v", fileName, err)
   151  		return mBlockSummaries, err
   152  	}
   153  
   154  	finfo, err := os.Stat(fileName)
   155  	if err != nil {
   156  		return mBlockSummaries, err
   157  	}
   158  
   159  	fileSize := finfo.Size()
   160  
   161  	fd, err := os.OpenFile(fileName, os.O_RDONLY, 0644)
   162  	if err != nil {
   163  		log.Infof("ReadMetricsBlockSummaries: failed to open fileName: %v  Error: %v.",
   164  			fileName, err)
   165  		return mBlockSummaries, err
   166  	}
   167  	defer fd.Close()
   168  
   169  	data := make([]byte, fileSize)
   170  	_, err = fd.Read(data)
   171  	if err != nil {
   172  		log.Errorf("ReadMetricsBlockSummaries: Error reading mbsu file: %v, err: %v", fileName, err)
   173  		return mBlockSummaries, err
   174  	}
   175  
   176  	versionBlockSummary := make([]byte, 1)
   177  	copy(versionBlockSummary, data[:1])
   178  	if versionBlockSummary[0] != utils.VERSION_MBLOCKSUMMARY[0] {
   179  		return mBlockSummaries, fmt.Errorf("ReadMetricsBlockSummaries: the file version doesn't match")
   180  	}
   181  	offset := int64(1)
   182  	for offset < fileSize {
   183  		blkNum := toputils.BytesToUint16LittleEndian(data[offset:])
   184  		offset += 2
   185  
   186  		// read highTs
   187  		highTs := toputils.BytesToUint32LittleEndian(data[offset:])
   188  		offset += 8
   189  
   190  		// read lowTs
   191  		lowTs := toputils.BytesToUint32LittleEndian(data[offset:])
   192  		offset += 8
   193  
   194  		blkSumm := &structs.MBlockSummary{HighTs: highTs,
   195  			LowTs:  lowTs,
   196  			Blknum: blkNum}
   197  
   198  		mBlockSummaries = append(mBlockSummaries, blkSumm)
   199  	}
   200  
   201  	return mBlockSummaries, nil
   202  }