returns (realOffset, data, error)
(ctx context.Context, offset int64, size int64, readFull bool)
| 204 | |
| 205 | // returns (realOffset, data, error) |
| 206 | func (entry *CacheEntry) readAt(ctx context.Context, offset int64, size int64, readFull bool) (int64, []byte, error) { |
| 207 | if offset < 0 { |
| 208 | return 0, nil, fmt.Errorf("offset cannot be negative") |
| 209 | } |
| 210 | file, err := entry.loadFileForRead(ctx) |
| 211 | if err != nil { |
| 212 | return 0, nil, err |
| 213 | } |
| 214 | if readFull { |
| 215 | size = file.Size - offset |
| 216 | } |
| 217 | if offset+size > file.Size { |
| 218 | size = file.Size - offset |
| 219 | } |
| 220 | if file.Opts.Circular { |
| 221 | realDataOffset := int64(0) |
| 222 | if file.Size > file.Opts.MaxSize { |
| 223 | realDataOffset = file.Size - file.Opts.MaxSize |
| 224 | } |
| 225 | if offset < realDataOffset { |
| 226 | truncateAmt := realDataOffset - offset |
| 227 | offset += truncateAmt |
| 228 | size -= truncateAmt |
| 229 | } |
| 230 | if size <= 0 { |
| 231 | return realDataOffset, nil, nil |
| 232 | } |
| 233 | } |
| 234 | partMap := file.computePartMap(offset, size) |
| 235 | dataEntryMap, err := entry.loadDataPartsForRead(ctx, getPartIdxsFromMap(partMap)) |
| 236 | if err != nil { |
| 237 | return 0, nil, err |
| 238 | } |
| 239 | // combine the entries into a single byte slice |
| 240 | // note that we only want part of the first and last part depending on offset and size |
| 241 | rtnData := make([]byte, 0, size) |
| 242 | amtLeftToRead := size |
| 243 | curReadOffset := offset |
| 244 | for amtLeftToRead > 0 { |
| 245 | partIdx := file.partIdxAtOffset(curReadOffset) |
| 246 | partDataEntry := dataEntryMap[partIdx] |
| 247 | var partData []byte |
| 248 | if partDataEntry == nil { |
| 249 | partData = make([]byte, partDataSize) |
| 250 | } else { |
| 251 | partData = partDataEntry.Data[0:partDataSize] |
| 252 | } |
| 253 | partOffset := curReadOffset % partDataSize |
| 254 | amtToRead := minInt64(partDataSize-partOffset, amtLeftToRead) |
| 255 | rtnData = append(rtnData, partData[partOffset:partOffset+amtToRead]...) |
| 256 | amtLeftToRead -= amtToRead |
| 257 | curReadOffset += amtToRead |
| 258 | } |
| 259 | return offset, rtnData, nil |
| 260 | } |
| 261 | |
| 262 | func prunePartsWithCache(dataEntries map[int]*DataCacheEntry, parts []int) []int { |
| 263 | var rtn []int |
no test coverage detected