Skip to content

Commit 628a542

Browse files
committed
fix(chunk): handle incomplete file chunks
1 parent 438e956 commit 628a542

1 file changed

Lines changed: 54 additions & 16 deletions

File tree

drivers/chunk/driver.go

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (d *Chunk) Get(ctx context.Context, path string) (model.Obj, error) {
8484
// 0号块默认为-1 以支持空文件
8585
chunkSizes := []int64{-1}
8686
h := make(map[*utils.HashType]string)
87-
var last model.Obj
87+
var first model.Obj
8888
for _, o := range chunkObjs {
8989
if o.IsDir() {
9090
continue
@@ -103,9 +103,11 @@ func (d *Chunk) Get(ctx context.Context, path string) (model.Obj, error) {
103103
if err != nil {
104104
continue
105105
}
106-
last = o
107106
totalSize += o.GetSize()
108107
if len(chunkSizes) > idx {
108+
if idx == 0 {
109+
first = o
110+
}
109111
chunkSizes[idx] = o.GetSize()
110112
} else if len(chunkSizes) == idx {
111113
chunkSizes = append(chunkSizes, o.GetSize())
@@ -117,21 +119,32 @@ func (d *Chunk) Get(ctx context.Context, path string) (model.Obj, error) {
117119
}
118120
}
119121
reqDir, _ := stdpath.Split(path)
120-
if last == nil {
122+
// 文件块不完整时,返回文件夹对象
123+
if chunkSizes[0] == -1 {
121124
return &model.Object{
122125
Path: stdpath.Join(reqDir, chunkName),
123126
Name: chunkName,
124127
IsFolder: true,
125128
Modified: d.Modified,
126129
}, nil
127130
}
131+
for i, l := 1, len(chunkSizes)-1; i < l; i++ {
132+
if chunkSizes[i] == 0 {
133+
return &model.Object{
134+
Path: stdpath.Join(reqDir, chunkName),
135+
Name: chunkName,
136+
IsFolder: true,
137+
Modified: d.Modified,
138+
}, nil
139+
}
140+
}
128141
objRes := chunkObject{
129142
Object: model.Object{
130143
Path: stdpath.Join(reqDir, chunkName),
131144
Name: name,
132145
Size: totalSize,
133-
Modified: last.ModTime(),
134-
Ctime: last.CreateTime(),
146+
Modified: first.ModTime(),
147+
Ctime: first.CreateTime(),
135148
},
136149
chunkSizes: chunkSizes,
137150
}
@@ -167,37 +180,51 @@ func (d *Chunk) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
167180
result = append(result, nil)
168181
listG.Go(func(ctx context.Context) error {
169182
chunkObjs, err := op.List(ctx, remoteStorage, stdpath.Join(remoteActualDir, rawName), model.ListArgs{
170-
ReqPath: stdpath.Join(args.ReqPath, rawName),
171183
Refresh: args.Refresh,
172184
})
173185
if err != nil {
174186
return err
175187
}
176-
totalSize := int64(0)
188+
var totalSize int64
189+
// 0号块默认为-1 以支持空文件
190+
chunkSizes := []int64{-1}
177191
h := make(map[*utils.HashType]string)
178-
var last model.Obj
192+
var first model.Obj
179193
for _, o := range chunkObjs {
180194
if o.IsDir() {
181195
continue
182196
}
183-
if after, ok := strings.CutPrefix(strings.TrimSuffix(o.GetName(), d.CustomExt), "hash_"); ok {
184-
hn, value, ok := strings.Cut(after, "_")
197+
if after, ok := strings.CutPrefix(o.GetName(), "hash_"); ok {
198+
hn, value, ok := strings.Cut(strings.TrimSuffix(after, d.CustomExt), "_")
185199
if ok {
186200
ht, ok := utils.GetHashByName(hn)
187201
if ok {
188202
h[ht] = value
189203
}
190-
continue
191204
}
205+
continue
192206
}
193-
_, err := strconv.Atoi(strings.TrimSuffix(o.GetName(), d.CustomExt))
207+
idx, err := strconv.Atoi(strings.TrimSuffix(o.GetName(), d.CustomExt))
194208
if err != nil {
195209
continue
196210
}
197-
last = o
198211
totalSize += o.GetSize()
212+
if len(chunkSizes) > idx {
213+
if idx == 0 {
214+
first = o
215+
}
216+
chunkSizes[idx] = o.GetSize()
217+
} else if len(chunkSizes) == idx {
218+
chunkSizes = append(chunkSizes, o.GetSize())
219+
} else {
220+
newChunkSizes := make([]int64, idx+1)
221+
copy(newChunkSizes, chunkSizes)
222+
chunkSizes = newChunkSizes
223+
chunkSizes[idx] = o.GetSize()
224+
}
199225
}
200-
if last == nil {
226+
// 文件块不完整时,返回文件夹对象
227+
if chunkSizes[0] == -1 {
201228
result[resultIdx] = &model.Object{
202229
Name: rawName,
203230
Size: obj.GetSize(),
@@ -206,11 +233,22 @@ func (d *Chunk) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
206233
}
207234
return nil
208235
}
236+
for i, l := 1, len(chunkSizes)-1; i < l; i++ {
237+
if chunkSizes[i] == 0 {
238+
result[resultIdx] = &model.Object{
239+
Name: rawName,
240+
Size: obj.GetSize(),
241+
Modified: obj.ModTime(),
242+
IsFolder: true,
243+
}
244+
return nil
245+
}
246+
}
209247
objRes := model.Object{
210248
Name: name,
211249
Size: totalSize,
212-
Modified: last.ModTime(),
213-
Ctime: last.CreateTime(),
250+
Modified: first.ModTime(),
251+
Ctime: first.CreateTime(),
214252
}
215253
if len(h) > 0 {
216254
objRes.HashInfo = utils.NewHashInfoByMap(h)

0 commit comments

Comments
 (0)