remotely-save/docs/sync_algorithm_v2.md
2022-03-11 09:47:46 +08:00

6.9 KiB

Sync Algorithm V2

Sources

We have 4 record sources:

  1. Local files. By scanning all files in the vault locally. Actually Obsidian provides an api directly returning this.
  2. Remote files. By scanning all files on the remote service. Some services provide an api directly returning this, and some other services require the plugin scanning the folders recursively.
  3. Local "delete-or-rename" history. It's recorded by using Obsidian's tracking api. So if users delete or rename files/folders outside Obsidian, we could do nothing.
  4. Remote "delete" history. It's uploaded by the plugin in each sync.

Assuming all sources are reliable.

Deal with them

We list all combinations mutually exclusive and collectively exhaustive.

Files

In short, we collect four timestamps, and respect the max timestamp and its corresponding operation.

t1 t2 t3 t4 local file to do remote file to do local del history to do remote del history to do equal to sync v2 branch
mtime_remote mtime_local deltime_remote deltime_local del_if_exists del_if_exists clean upload_local_del_history
mtime_local mtime_remote deltime_remote deltime_local del_if_exists del_if_exists clean upload_local_del_history
mtime_remote deltime_remote mtime_local deltime_local del_if_exists del_if_exists clean upload_local_del_history
deltime_remote mtime_remote mtime_local deltime_local del_if_exists del_if_exists clean upload_local_del_history
mtime_local deltime_remote mtime_remote deltime_local del_if_exists del_if_exists clean upload_local_del_history
deltime_remote mtime_local mtime_remote deltime_local del_if_exists del_if_exists clean upload_local_del_history 8
mtime_remote mtime_local deltime_local deltime_remote del_if_exists del_if_exists clean keep
mtime_local mtime_remote deltime_local deltime_remote del_if_exists del_if_exists clean keep
mtime_remote deltime_local mtime_local deltime_remote del_if_exists del_if_exists clean keep
deltime_local mtime_remote mtime_local deltime_remote del_if_exists del_if_exists clean keep
mtime_local deltime_local mtime_remote deltime_remote del_if_exists del_if_exists clean keep
deltime_local mtime_local mtime_remote deltime_remote del_if_exists del_if_exists clean keep
mtime_remote deltime_remote deltime_local mtime_local skip upload_local clean clean
deltime_remote mtime_remote deltime_local mtime_local skip upload_local clean clean 10
mtime_remote deltime_local deltime_remote mtime_local skip upload_local clean clean
deltime_local mtime_remote deltime_remote mtime_local skip upload_local clean clean
deltime_remote deltime_local mtime_remote mtime_local skip upload_local clean clean 2;3;4;5;6
deltime_local deltime_remote mtime_remote mtime_local skip upload_local clean clean
mtime_local deltime_remote deltime_local mtime_remote download_remote skip clean clean
deltime_remote mtime_local deltime_local mtime_remote download_remote skip clean clean 7;9
mtime_local deltime_local deltime_remote mtime_remote download_remote skip clean clean
deltime_local mtime_local deltime_remote mtime_remote download_remote skip clean clean
deltime_remote deltime_local mtime_local mtime_remote download_remote skip clean clean 1;9
deltime_local deltime_remote mtime_local mtime_remote download_remote skip clean clean

Folders

We actually do not use any folders' metadata. Thus the only relevent info is their names, while the mtime is actually ignorable.

  1. Firstly generate all the files' plan. If any files exist, then it's parent folders all should exist. If the should-exist folder doesn't exist locally, the local should create it recursively. If the should-exist folder doesn't exist remotely, the remote should create it recursively.

  2. Then, a folder is deletable, if and only if all the following conditions meet:

    • it shows up in the remote deletion history
    • it's empty, or all its sub-folders are deletable

    Some examples:

    • A user deletes the folder in device 1, then syncs from the device 1, then creates the same-name folder in device 2, then syncs from the device 2. The folder is deleted (again), on device 2.
    • A user deletes the folder in device 1, then syncs from the device 1, then creates the same-name folder in device 2, then create a new file inside it, then syncs from the device 2. The folder is kept instead of deleted because of the new file, on device 2.
    • A user deletes the folder in device 1, then syncs from the device 1, then do not touch the same-name folder in device 2, then syncs from the device 2. The folder and its untouched sub-files should be deleted on device 2.