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 }