|
@ -13,7 +13,8 @@ type FileChunkSection struct { |
|
|
visibleIntervals *IntervalList[*VisibleInterval] |
|
|
visibleIntervals *IntervalList[*VisibleInterval] |
|
|
chunkViews *IntervalList[*ChunkView] |
|
|
chunkViews *IntervalList[*ChunkView] |
|
|
reader *ChunkReadAt |
|
|
reader *ChunkReadAt |
|
|
lock sync.Mutex |
|
|
|
|
|
|
|
|
lock sync.RWMutex |
|
|
|
|
|
isPrepared bool |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func NewFileChunkSection(si SectionIndex) *FileChunkSection { |
|
|
func NewFileChunkSection(si SectionIndex) *FileChunkSection { |
|
@ -61,6 +62,19 @@ func removeGarbageChunks(section *FileChunkSection, garbageFileIds map[string]st |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (section *FileChunkSection) setupForRead(group *ChunkGroup, fileSize int64) { |
|
|
func (section *FileChunkSection) setupForRead(group *ChunkGroup, fileSize int64) { |
|
|
|
|
|
if section.isPrepared { |
|
|
|
|
|
section.reader.fileSize = fileSize |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
section.lock.Lock() |
|
|
|
|
|
defer section.lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
if section.isPrepared { |
|
|
|
|
|
section.reader.fileSize = fileSize |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if section.visibleIntervals == nil { |
|
|
if section.visibleIntervals == nil { |
|
|
section.visibleIntervals = readResolvedChunks(section.chunks, int64(section.sectionIndex)*SectionSize, (int64(section.sectionIndex)+1)*SectionSize) |
|
|
section.visibleIntervals = readResolvedChunks(section.chunks, int64(section.sectionIndex)*SectionSize, (int64(section.sectionIndex)+1)*SectionSize) |
|
|
section.chunks, _ = SeparateGarbageChunks(section.visibleIntervals, section.chunks) |
|
|
section.chunks, _ = SeparateGarbageChunks(section.visibleIntervals, section.chunks) |
|
@ -76,23 +90,25 @@ func (section *FileChunkSection) setupForRead(group *ChunkGroup, fileSize int64) |
|
|
if section.reader == nil { |
|
|
if section.reader == nil { |
|
|
section.reader = NewChunkReaderAtFromClient(group.readerCache, section.chunkViews, min(int64(section.sectionIndex+1)*SectionSize, fileSize)) |
|
|
section.reader = NewChunkReaderAtFromClient(group.readerCache, section.chunkViews, min(int64(section.sectionIndex+1)*SectionSize, fileSize)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
section.isPrepared = true |
|
|
section.reader.fileSize = fileSize |
|
|
section.reader.fileSize = fileSize |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (section *FileChunkSection) readDataAt(group *ChunkGroup, fileSize int64, buff []byte, offset int64) (n int, tsNs int64, err error) { |
|
|
func (section *FileChunkSection) readDataAt(group *ChunkGroup, fileSize int64, buff []byte, offset int64) (n int, tsNs int64, err error) { |
|
|
section.lock.Lock() |
|
|
|
|
|
defer section.lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
section.setupForRead(group, fileSize) |
|
|
section.setupForRead(group, fileSize) |
|
|
|
|
|
section.lock.RLock() |
|
|
|
|
|
defer section.lock.RUnlock() |
|
|
|
|
|
|
|
|
return section.reader.ReadAtWithTime(buff, offset) |
|
|
return section.reader.ReadAtWithTime(buff, offset) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (section *FileChunkSection) DataStartOffset(group *ChunkGroup, offset int64, fileSize int64) int64 { |
|
|
func (section *FileChunkSection) DataStartOffset(group *ChunkGroup, offset int64, fileSize int64) int64 { |
|
|
section.lock.Lock() |
|
|
|
|
|
defer section.lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
section.setupForRead(group, fileSize) |
|
|
section.setupForRead(group, fileSize) |
|
|
|
|
|
section.lock.RLock() |
|
|
|
|
|
defer section.lock.RUnlock() |
|
|
|
|
|
|
|
|
for x := section.visibleIntervals.Front(); x != nil; x = x.Next { |
|
|
for x := section.visibleIntervals.Front(); x != nil; x = x.Next { |
|
|
visible := x.Value |
|
|
visible := x.Value |
|
@ -108,10 +124,10 @@ func (section *FileChunkSection) DataStartOffset(group *ChunkGroup, offset int64 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (section *FileChunkSection) NextStopOffset(group *ChunkGroup, offset int64, fileSize int64) int64 { |
|
|
func (section *FileChunkSection) NextStopOffset(group *ChunkGroup, offset int64, fileSize int64) int64 { |
|
|
section.lock.Lock() |
|
|
|
|
|
defer section.lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
section.setupForRead(group, fileSize) |
|
|
section.setupForRead(group, fileSize) |
|
|
|
|
|
section.lock.RLock() |
|
|
|
|
|
defer section.lock.RUnlock() |
|
|
|
|
|
|
|
|
isAfterOffset := false |
|
|
isAfterOffset := false |
|
|
for x := section.visibleIntervals.Front(); x != nil; x = x.Next { |
|
|
for x := section.visibleIntervals.Front(); x != nil; x = x.Next { |
|
|