Map是承载离线/在线数据快照的关键容器,通过键值对管理带逻辑时钟、版本标记与操作类型的变更记录,支撑基于Key对齐的冲突检测、向量时钟协同及字段级轻量合并策略。

Map 本身不是同步算法,但它是非常关键的底层容器工具——用来承载、索引、比对和组织离线与在线数据的状态快照。真正实现“复杂离线同步与冲突合并”的,是一套基于 Map 构建的元数据管理机制,核心在于用键(Key)锚定实体,用值(Value)封装带逻辑时钟、版本标记、操作类型等上下文的变更记录。
用 Map 管理本地与服务端数据快照
在离线阶段,每次用户修改某条记录(如订单 ID = "ORD-1001"),不直接覆盖原始数据,而是将该记录的完整状态 + 元信息存入一个本地 Map:
- Key:业务主键(如 "ORD-1001"),确保全局唯一可寻址;
- Value:结构化对象,至少包含:data(当前内容)、version(Lamport 时间戳或向量时钟)、status("created"/"updated"/"deleted")、local_ts(本地生成时间,仅作日志参考)。
同理,从服务器拉取的最新数据也加载进另一个 Map(如 serverState)。两个 Map 的 Key 集合交集,就是需要做冲突判断的候选集。
基于 Key 对齐的冲突检测逻辑
联网后遍历 localState 中每个 Key,检查它是否存在于 serverState 中,并比较双方的逻辑版本:
- 若只在 localState 中存在 → 视为新增,直接提交;
- 若只在 serverState 中存在 → 视为远程新增,本地拉取合并;
- 若双方都存在,且 localState[key].version > serverState[key].version → 本地更新更“新”,采用本地值(需携带 version 提交);
- 若双方都存在,但 version 相等 → 潜在并发修改,触发业务级冲突策略(如字段级合并、保留最后写入、弹窗提示人工介入);
- 若 localState[key].version → 本地已过期,需先拉取最新版,再将本地变更以“增量 patch”方式重新应用(类似 Git rebase)。
用嵌套 Map 支持向量时钟与多端协同
当应用支持多设备登录(如手机+平板+网页),单一 Lamport 时间戳无法区分来源。此时可用嵌套 Map 表达向量时钟(Vector Clock):
-
version: Map
,例如 {"mobile": 5, "web": 3, "server": 7}; - 每次本地修改,“自己设备名”对应计数器 +1;发送同步请求时带上整个 Map;
- 服务端收到后,逐项取 max 并更新自己的向量时钟,再回传;
- 客户端收到响应后,同样执行 max 合并,保证各端逻辑时间单调增长、可偏序比较。
这种结构天然适合 Java/Go/TypeScript 中的 Map 或 Object 类型,无需额外序列化开销。
Map 驱动的轻量级冲突合并策略
对于文档类、表单类数据,可定义字段粒度的合并规则,并用 Map 存储策略映射:
- 定义 mergePolicy: Map
,如 {"title": "last-write-wins", "content": "auto-merge", "tags": "union"}; - 检测到冲突时,按字段查此 Map,决定如何处理:
• “last-write-wins”:直接用 version 更高一方的值;
• “auto-merge”:调用 diff-match-patch 或类似算法合并文本差异;
• “union”:对数组类字段做去重并集。
这样,同一张表不同字段可启用不同语义的合并逻辑,灵活性远超全量覆盖或全量拒绝。










