|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package cache
-
- import (
- "gitlink.org.cn/cloudream/common/utils/lo2"
- "gitlink.org.cn/cloudream/common/utils/math2"
- )
-
- type SegmentType int
-
- const (
- // 数据段刚被初始化
- SegmentInit = iota
- // 数据来自本地文件
- SegmentLocal
- // 数据来自远端文件,还未写入到本地文件
- SegmentRemote
- // 数据由用户写入,还未写入到本地文件
- SegmentDirty
- )
-
- type FileSegment struct {
- Position int64
- // 有效数据的长度。不一定等于Buffer的长度
- Length int64
- Type SegmentType
- // 文件数据缓冲区。不可对此缓冲区进行append操作!
- Buffer []byte
- // 当前段是否正在被保存到本地文件中
- IsSaving bool
- // 引用计数。当引用计数为0时,可以安全地删除此段
- RefCount int
- }
-
- func (s *FileSegment) GetPosition() int64 {
- return s.Position
- }
-
- func (s *FileSegment) GetLength() int64 {
- return s.Length
- }
-
- func (s *FileSegment) SubSliceAbs(pos int64, len int64) []byte {
- start := pos - s.Position
- return s.Buffer[start : start+len]
- }
-
- // 将当前段拆分为两个段。当前段将持有第一个段,返回值持有第二个段
- func (s *FileSegment) SplitAbs(pos int64) *FileSegment {
- s2 := s.Buffer[pos-s.Position:]
- s2Len := math2.Max(s.Position+s.Length-pos, 0)
-
- s.Buffer = s.Buffer[:pos-s.Position]
- s.Length = math2.Min(int64(len(s.Buffer)), s.Length)
-
- return &FileSegment{
- Position: pos,
- Length: s2Len,
- Type: s.Type,
- Buffer: s2,
- }
- }
-
- func (s *FileSegment) AvailableEnd() int64 {
- return s.Position + s.Length
- }
-
- func (s *FileSegment) BufferEnd() int64 {
- return s.Position + int64(len(s.Buffer))
- }
-
- func (s *FileSegment) EnlargeTo(pos int64) {
- if pos > s.Position+s.Length {
- s.Length = pos - s.Position
- }
- }
-
- type SegmentBuffer struct {
- // 正在使用的文件段缓冲区
- buzys []*FileSegment
- }
-
- func (s *SegmentBuffer) BuzyCount() int {
- return len(s.buzys)
- }
-
- func (s *SegmentBuffer) Segment(idx int) *FileSegment {
- return s.buzys[idx]
- }
-
- func (s *SegmentBuffer) FirstContains(pos int64) int {
- return FirstContains(s.buzys, pos)
- }
-
- // 将指定段插入到段缓存的恰当位置
- func (s *SegmentBuffer) Insert(seg *FileSegment) {
- index := s.FirstContains(seg.Position)
-
- if index == -1 {
- s.buzys = append([]*FileSegment{seg}, s.buzys...)
- } else {
- // index是最后一个小于Position的位置,所以要加1
- s.buzys = lo2.Insert(s.buzys, index+1, seg)
- }
- }
-
- // 插入一个段到指定索引位置。不会检查插入后Segments是否依然保持有序。
- func (s *SegmentBuffer) InsertAt(index int, seg *FileSegment) {
- s.buzys = lo2.Insert(s.buzys, index, seg)
- }
-
- func (s *SegmentBuffer) RemoveAt(index int) {
- s.buzys = lo2.RemoveAt(s.buzys, index)
- }
-
- func (s *SegmentBuffer) Remove(seg *FileSegment) {
- s.buzys = lo2.Remove(s.buzys, seg)
- }
|