This repository has been archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[core] Evict cached resources and tiles equally by access time #7770
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -792,6 +792,31 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { | |
// The addition of pageSize is a fudge factor to account for non `data` column | ||
// size, and because pages can get fragmented on the database. | ||
while (usedSize() + neededFreeSize + pageSize > maximumCacheSize) { | ||
// clang-format off | ||
Statement accessedStmt = getStatement( | ||
"SELECT max(accessed) " | ||
"FROM ( " | ||
" SELECT accessed " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure the inner query is parsed as suggested by the indentation, and not "(select from resources [unordered and unlimited]) UNION ALL (select from tiles ... ordery by ... limit 50)"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #7755 (comment) |
||
" FROM resources " | ||
" LEFT JOIN region_resources " | ||
" ON resource_id = resources.id " | ||
" WHERE resource_id IS NULL " | ||
" UNION ALL " | ||
" SELECT accessed " | ||
" FROM tiles " | ||
" LEFT JOIN region_tiles " | ||
" ON tile_id = tiles.id " | ||
" WHERE tile_id IS NULL " | ||
" ORDER BY accessed ASC LIMIT ?1 " | ||
") " | ||
); | ||
accessedStmt->bind(1, 50); | ||
// clang-format on | ||
if (!accessedStmt->run()) { | ||
return false; | ||
} | ||
Timestamp accessed = accessedStmt->get<Timestamp>(0); | ||
|
||
// clang-format off | ||
Statement stmt1 = getStatement( | ||
"DELETE FROM resources " | ||
|
@@ -800,10 +825,10 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { | |
" LEFT JOIN region_resources " | ||
" ON resource_id = resources.id " | ||
" WHERE resource_id IS NULL " | ||
" ORDER BY accessed ASC LIMIT ?1 " | ||
" AND accessed <= ?1 " | ||
") "); | ||
// clang-format on | ||
stmt1->bind(1, 50); | ||
stmt1->bind(1, accessed); | ||
stmt1->run(); | ||
uint64_t changes1 = db->changes(); | ||
|
||
|
@@ -815,10 +840,10 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { | |
" LEFT JOIN region_tiles " | ||
" ON tile_id = tiles.id " | ||
" WHERE tile_id IS NULL " | ||
" ORDER BY accessed ASC LIMIT ?1 " | ||
" AND accessed <= ?1 " | ||
") "); | ||
// clang-format on | ||
stmt2->bind(1, 50); | ||
stmt2->bind(1, accessed); | ||
stmt2->run(); | ||
uint64_t changes2 = db->changes(); | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Query plan for this:
This concerns me a bit: it's table scanning both
resources
andtiles
. The scan is done on indexes that are ordered appropriately for theORDER BY ... LIMIT
clause, and the hope is that these scans will be run in parallel, and both aborted when the limit is reached. But the query plan doesn't really make clear whether that's the case or not. It would be bad if the tables both had to be scanned in full.Can you do some benchmarking over databases of a few different sizes (empty, just ambient use, large offline region), and see how query time scales empirically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a similar concern, since as part of the union it seem it would need to load the entirety of each table before sorting.
The below query adds complexity but leverages the indexes within subqueries before the union:
And has the following query plan:
I've used sqlite's built in
.timer ON
to attempt to profile the queries, and the differences seem negligible for a full cache (50mb database, 1010 tiles, 9 resources) but no offline regions stored.Query in commit:
Run Time: real 0.000 user 0.000155 sys 0.000076
Query in comment:
Run Time: real 0.000 user 0.000207 sys 0.000120
I'm not sure of a better way to profile sqlite here, and not sure if those query results are cached. Let me know if you have any ideas, couldn't find much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems promising. It's pretty important that we don't regress eviction performance for larger databases too, so can you test both approaches with a large offline region as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing on a database with SF downloaded for offline: 153mb, 3300 tiles, 1284 resources
Query in commit, run 3x:
Query in comment:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Let's go with the simpler query then.