123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package erasure_coding
- import (
- "github.com/seaweedfs/seaweedfs/weed/storage/types"
- )
- type Interval struct {
- BlockIndex int // the index of the block in either the large blocks or the small blocks
- InnerBlockOffset int64
- Size types.Size
- IsLargeBlock bool // whether the block is a large block or a small block
- LargeBlockRowsCount int
- }
- func LocateData(largeBlockLength, smallBlockLength int64, shardDatSize int64, offset int64, size types.Size) (intervals []Interval) {
- blockIndex, isLargeBlock, nLargeBlockRows, innerBlockOffset := locateOffset(largeBlockLength, smallBlockLength, shardDatSize, offset)
- for size > 0 {
- interval := Interval{
- BlockIndex: blockIndex,
- InnerBlockOffset: innerBlockOffset,
- IsLargeBlock: isLargeBlock,
- LargeBlockRowsCount: int(nLargeBlockRows),
- }
- blockRemaining := largeBlockLength - innerBlockOffset
- if !isLargeBlock {
- blockRemaining = smallBlockLength - innerBlockOffset
- }
- if int64(size) <= blockRemaining {
- interval.Size = size
- intervals = append(intervals, interval)
- return
- }
- interval.Size = types.Size(blockRemaining)
- intervals = append(intervals, interval)
- size -= interval.Size
- blockIndex += 1
- if isLargeBlock && blockIndex == interval.LargeBlockRowsCount*DataShardsCount {
- isLargeBlock = false
- blockIndex = 0
- }
- innerBlockOffset = 0
- }
- return
- }
- func locateOffset(largeBlockLength, smallBlockLength int64, shardDatSize int64, offset int64) (blockIndex int, isLargeBlock bool, nLargeBlockRows int64, innerBlockOffset int64) {
- largeRowSize := largeBlockLength * DataShardsCount
- nLargeBlockRows = (shardDatSize-1)/ largeBlockLength
- // 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
- }
- func (interval Interval) ToShardIdAndOffset(largeBlockSize, smallBlockSize int64) (ShardId, int64) {
- ecFileOffset := interval.InnerBlockOffset
- rowIndex := interval.BlockIndex / DataShardsCount
- if interval.IsLargeBlock {
- ecFileOffset += int64(rowIndex) * largeBlockSize
- } else {
- ecFileOffset += int64(interval.LargeBlockRowsCount)*largeBlockSize + int64(rowIndex)*smallBlockSize
- }
- ecFileIndex := interval.BlockIndex % DataShardsCount
- return ShardId(ecFileIndex), ecFileOffset
- }
|