mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-04 12:36:37 +08:00
fix(sync): deduplicate remoteMeta by file ID to prevent deleting valid remote metadata copies
This commit is contained in:
@@ -1341,6 +1341,7 @@ func (st *strmSyncState) localSha1Matches(path, remoteSha1 string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// recordRemoteMeta 记录远端存在的元数据索引、文件大小、文件引用及内容 SHA1(多副本聚合追加)。
|
// recordRemoteMeta 记录远端存在的元数据索引、文件大小、文件引用及内容 SHA1(多副本聚合追加)。
|
||||||
|
// 对同一文件 ID 严格去重,避免当 download_meta 与 upload_meta 同时开启时因重复记录引发误判与自杀式删除。
|
||||||
func (st *strmSyncState) recordRemoteMeta(entry cloud.FileEntry, rel string) {
|
func (st *strmSyncState) recordRemoteMeta(entry cloud.FileEntry, rel string) {
|
||||||
st.mu.Lock()
|
st.mu.Lock()
|
||||||
defer st.mu.Unlock()
|
defer st.mu.Unlock()
|
||||||
@@ -1349,6 +1350,13 @@ func (st *strmSyncState) recordRemoteMeta(entry cloud.FileEntry, rel string) {
|
|||||||
}
|
}
|
||||||
key := "m:" + rel
|
key := "m:" + rel
|
||||||
st.seenMeta[key] = true
|
st.seenMeta[key] = true
|
||||||
|
if entry.ID != "" {
|
||||||
|
for _, existing := range st.remoteMeta[key] {
|
||||||
|
if existing.ID == entry.ID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
st.remoteMeta[key] = append(st.remoteMeta[key], remoteMetaItem{
|
st.remoteMeta[key] = append(st.remoteMeta[key], remoteMetaItem{
|
||||||
ID: entry.ID,
|
ID: entry.ID,
|
||||||
Size: entry.Size,
|
Size: entry.Size,
|
||||||
@@ -1624,21 +1632,23 @@ func (st *strmSyncState) scanLocalMetaForUpload() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if matchedIdx >= 0 {
|
if matchedIdx >= 0 {
|
||||||
// 远端已存在完全一致的副本,跳过上传!
|
// 远端已存在完全一致的副本,跳过上传!
|
||||||
// 若远端还存在其他同名脏副本(副本总数 > 1),在 115 下收集待删除 ID,稍后按目录批量删除
|
// 若远端还存在其他同名脏副本(副本总数 > 1),在 115 下收集待删除 ID,稍后按目录批量删除。
|
||||||
if len(entries) > 1 && st.p.Provider == model.StrmProvider115 {
|
// 严禁将已命中的最新副本 ID (matchedID) 放入待删列表,杜绝误杀唯一有效副本。
|
||||||
parentCID := st.uploadRemoteTarget(rel)
|
if len(entries) > 1 && st.p.Provider == model.StrmProvider115 {
|
||||||
if parentCID != "" {
|
parentCID := st.uploadRemoteTarget(rel)
|
||||||
for i, it := range entries {
|
if parentCID != "" {
|
||||||
if i != matchedIdx && it.ID != "" {
|
matchedID := entries[matchedIdx].ID
|
||||||
pendingDeletes[parentCID] = append(pendingDeletes[parentCID], it.ID)
|
for i, it := range entries {
|
||||||
|
if i != matchedIdx && it.ID != "" && it.ID != matchedID {
|
||||||
|
pendingDeletes[parentCID] = append(pendingDeletes[parentCID], it.ID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteTarget := st.uploadRemoteTarget(rel)
|
remoteTarget := st.uploadRemoteTarget(rel)
|
||||||
|
|||||||
@@ -1320,6 +1320,30 @@ func TestScanLocalMetaForUploadMultipleCopiesAllStale(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestRecordRemoteMetaDeduplication 验证当 download_meta 与 upload_meta 同时开启时,
|
||||||
|
// 同一远端元数据被多次入账不会在 remoteMeta 中生成重复副本,杜绝误判自杀式删除。
|
||||||
|
func TestRecordRemoteMetaDeduplication(t *testing.T) {
|
||||||
|
st := &strmSyncState{
|
||||||
|
seenMeta: map[string]bool{},
|
||||||
|
remoteMeta: map[string][]remoteMetaItem{},
|
||||||
|
}
|
||||||
|
entry := cloud.FileEntry{
|
||||||
|
ID: "unique-fid-1",
|
||||||
|
Name: "test.nfo",
|
||||||
|
Size: 100,
|
||||||
|
Sha1: "AAAABBBBCCCC",
|
||||||
|
MTime: 12345,
|
||||||
|
}
|
||||||
|
// 连续记录两次同一文件
|
||||||
|
st.recordRemoteMeta(entry, "dir/test.nfo")
|
||||||
|
st.recordRemoteMeta(entry, "dir/test.nfo")
|
||||||
|
|
||||||
|
items := st.remoteMeta["m:dir/test.nfo"]
|
||||||
|
if len(items) != 1 {
|
||||||
|
t.Fatalf("expected 1 item after duplicate record, got %d", len(items))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestWalk115AdaptiveHierarchicalFlatScan 验证自适应分治扁平化扫描:
|
// TestWalk115AdaptiveHierarchicalFlatScan 验证自适应分治扁平化扫描:
|
||||||
// 当根目录探测总数 >= 9500 时,系统自动分治展开单层直接子项,对各子目录分别执行扁平拉取,
|
// 当根目录探测总数 >= 9500 时,系统自动分治展开单层直接子项,对各子目录分别执行扁平拉取,
|
||||||
// 正确合并根目录直属文件与各子目录深层文件,突破 115 开放平台 10000 深度限制。
|
// 正确合并根目录直属文件与各子目录深层文件,突破 115 开放平台 10000 深度限制。
|
||||||
|
|||||||
Reference in New Issue
Block a user