|
|
package erasure_coding
type Interval struct { blockIndex int innerBlockOffset int64 size uint32 isLargeBlock bool }
func locateData(largeBlockLength, smallBlockLength int64, datSize int64, offset int64, size uint32) (intervals []Interval) { blockIndex, isLargeBlock, innerBlockOffset := locateOffset(largeBlockLength, smallBlockLength, datSize, offset)
nLargeBlockRows := int(datSize / (largeBlockLength * DataShardsCount))
for size > 0 { interval := Interval{ blockIndex: blockIndex, innerBlockOffset: innerBlockOffset, isLargeBlock: isLargeBlock, }
blockRemaining := largeBlockLength - innerBlockOffset if !isLargeBlock { blockRemaining = smallBlockLength - innerBlockOffset }
if int64(size) <= blockRemaining { interval.size = size intervals = append(intervals, interval) return } interval.size = uint32(blockRemaining) intervals = append(intervals, interval)
size -= interval.size blockIndex += 1 if isLargeBlock && blockIndex == nLargeBlockRows*DataShardsCount { isLargeBlock = false blockIndex = 0 } innerBlockOffset = 0
} return }
func locateOffset(largeBlockLength, smallBlockLength int64, datSize int64, offset int64) (blockIndex int, isLargeBlock bool, innerBlockOffset int64) { largeRowSize := largeBlockLength * DataShardsCount nLargeBlockRows := datSize / (largeBlockLength * DataShardsCount)
// if offset is within the large block area
if offset < nLargeBlockRows*largeRowSize { isLargeBlock = true blockIndex, innerBlockOffset = locateOffsetWithinBlocks(largeBlockLength, offset) return }
isLargeBlock = false offset -= nLargeBlockRows * largeRowSize blockIndex, innerBlockOffset = locateOffsetWithinBlocks(smallBlockLength, offset) return }
func locateOffsetWithinBlocks(blockLength int64, offset int64) (blockIndex int, innerBlockOffset int64) { blockIndex = int(offset / blockLength) innerBlockOffset = offset % blockLength return }
|