Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/db: Add index to track locally needed files #4958

Merged
merged 3 commits into from Jun 2, 2018

Conversation

imsodin
Copy link
Member

@imsodin imsodin commented May 17, 2018

Purpose

While I'm doing that you can think about the other half of the equation. :) For every incoming index update we schedule a pull. The pull looks through the database for things that have changed...
#4906 (comment)

It took me a while longer than it took Jakob to test it, but here it is.

The needKey->nil bucket tracks locally needed files and is update whenever files are updated. Thus traversing local needs does no longer need to go over the entire global bucket detecting what we actually need, it just walks this new bucket. For remote devices I don't do the same for less complexity and smaller db size, as lookups of remote needs are less frequent - that works just like before.

Some of the refactoring is due to an earlier version of the new test that worked without the jsons db and thus needed access to parts of readWriteTransaction.updateGlobal. In my opinion the refactor is still worthwhile.

The l -> fl/vl renaming is to not override the logger variable.

Testing

I added a test for the db migration from schema 0 to 3.

Edit:
I didn't the database schema change in the local flags PR. Just ignore that aspect in the review, depending on timeline I will adjust this PR accordingly or do a separate PR for that shuffling.

To optimize WithNeed, which is called for the local device whenever an index
update is received. No tracking for remote devices to conserve db space, as
WithNeed is only queried for completion.
@calmh
Copy link
Member

calmh commented May 17, 2018

Sounds awesome; will take some pondering to review properly as it's important, so bear with me. :)

// the metadata if we replace it.
oldFile, hasOldFile = t.getFile(folder, fl.Versions[0].Device, name)
}
if insertedAt == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to take into account here that I had to fix up in updateGlobal for receive only, and that I think can be an issue already without the receive only stuff...

If we update a local file to a lower version than what is currently in there, what is the head of the version list may change without the insert being at index zero. For receive only folders this happens when the user does a "revert", but I think it could happen already today when a file gets unignored as we then tweak the version. Whether the new version becomes the head of the list or not depends on conflict resolution, and if it does not win the resolution it'll be inserted somewhere in the middle.

So, basically, if the version list is {F1, F2, F3} where F1 is our local file and the need is nil (we have the latest version), an update after unignore (or the upcoming revert operation) can make it {F2, F1', F3} or {F2, F3, F1'}, where F1' is the version-tweaked unignored file.

We need to make F2 the needed version then, despite the insert happening somewhere further down the list.

After receive only folders it becomes worse, although that's not your problem at the moment. :) The head of the list can then be a version we need, which gets withdrawn due to a change happening on that receive only device, and potentially another version from another device then becomes promoted to the head of the list and becomes the new needed file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely true, removedAt == 0 needs to be handled as well - thanks for catching that.
Doesn't that mean that global meta counting is broken already in this scenario?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think so. I have it fixed but it's on top of a couple of other things, and of course it interferes with this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not block fixing that on this PR: #4968

@AudriusButkevicius
Copy link
Member

Again, db stuff magic, 3 or 4 years later I still don't understand it well, so I'll leave it for you guys.

Copy link
Member

@calmh calmh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks correct to me, but there is a bunch of commented out code and stuff.

@imsodin
Copy link
Member Author

imsodin commented May 30, 2018

@calmh Should be clean now (commented tests are "generator" tests).

I can post a followup-PR for the db-update refactor that you propose in your local flags PR, good idea?

@calmh calmh merged commit 5baa432 into syncthing:master Jun 2, 2018
@calmh
Copy link
Member

calmh commented Jun 2, 2018

@imsodin 👍 please do

@imsodin imsodin deleted the needDB branch June 2, 2018 14:28
@calmh calmh added this to the v0.14.49 milestone Jun 5, 2018
@calmh calmh changed the title lib/db: Add prefix to track locally needed files lib/db: Add index to track locally needed files Jun 5, 2018
calmh added a commit to calmh/syncthing that referenced this pull request Jun 8, 2018
* master:
  lib/protocol: Test for IsEquivalent (syncthing#4996)
  gui: Add tabs in device editor (syncthing#4986)
  lib/config, lib/model: Handle shared with information in config (fixes syncthing#4870) (syncthing#4974)
  gui: Restrict shown decimals and restrict size of header columns (syncthing#4973)
  cmd/stfindignored: Default to current directory
  cmd/stfindignored: Make that 2018
  cmd/stfindignored: Add utility
  gui: Hide allowed networks if unused (syncthing#4989)
  lib/protocol: Correct block size calculation on 32 bit archs (fixes syncthing#4990) (syncthing#4991)
  lib/upgrade: Tests should pass on darwin-386
  gui, man: Update docs & translations
  gui: Don't remove the slash from path '/' (fixes syncthing#4983) (syncthing#4988)
  lib/fs: Resolve 8.3 filenames from watcher (ref syncthing#3800) (syncthing#4975)
  lib/scanner: Skip block size hysteresis test in -short mode
  lib/db: Add index to track locally needed files (syncthing#4958)
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Jun 3, 2019
@syncthing syncthing locked and limited conversation to collaborators Jun 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants