diff --git a/weed/filer/filechunk_section.go b/weed/filer/filechunk_section.go index 60c919569..5804c7160 100644 --- a/weed/filer/filechunk_section.go +++ b/weed/filer/filechunk_section.go @@ -32,10 +32,17 @@ func (section *FileChunkSection) addChunk(chunk *filer_pb.FileChunk) error { if section.visibleIntervals != nil { MergeIntoVisibles(section.visibleIntervals, start, stop, chunk) - } - - if section.visibleIntervals != nil { - section.chunks, _ = SeparateGarbageChunks(section.visibleIntervals, section.chunks) + garbageFileIds := FindGarbageChunks(section.visibleIntervals, start, stop) + for _, garbageFileId := range garbageFileIds { + length := len(section.chunks) + for i, t := range section.chunks { + if t.FileId == garbageFileId { + section.chunks[i] = section.chunks[length-1] + section.chunks = section.chunks[:length-1] + break + } + } + } } if section.chunkViews != nil { diff --git a/weed/filer/filechunks.go b/weed/filer/filechunks.go index d872bd22d..480478fd7 100644 --- a/weed/filer/filechunks.go +++ b/weed/filer/filechunks.go @@ -86,6 +86,17 @@ func SeparateGarbageChunks(visibles *IntervalList[*VisibleInterval], chunks []*f return compacted, garbage } +func FindGarbageChunks(visibles *IntervalList[*VisibleInterval], start int64, stop int64) (garbageFileId []string) { + for x := visibles.Front(); x != nil; x = x.Next { + interval := x.Value + offset := interval.start - interval.offsetInChunk + if start <= offset && offset+int64(interval.chunkSize) <= stop { + garbageFileId = append(garbageFileId, interval.fileId) + } + } + return +} + func MinusChunks(lookupFileIdFn wdclient.LookupFileIdFunctionType, as, bs []*filer_pb.FileChunk) (delta []*filer_pb.FileChunk, err error) { aData, aMeta, aErr := ResolveChunkManifest(lookupFileIdFn, as, 0, math.MaxInt64)