-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
DESIGN
48 lines (38 loc) · 1.69 KB
/
DESIGN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
See manifest.sql for the manifest DB schema.
DB instance are identified by their dir path.
DB instance clients have:
* Lazily created exclusive files for writing new values in parallel without locking the manifest.
* A sqlite3 connection to the manifest file.
* A cache of exclusive files ready for writing
* A cache of file clones, invalidated as necessary
A snapshot has:
* One or more cloned value files.
write values for keys:
* append to exclusive file
* hash parts? (not implemented)
* take exclusive write lock on manifest
* add entries to manifest
* unlock manifest
* punching blocks from new writes that are duplicates
* evict and punch holes until size below max
for a read:
* open manifest for deferred write (in case we abort the read, or the values we want are missing)
* for each read key, update the last_used and copy out the value location
* clone any files that contain regions to be streamed out
* unlock manifest
* return snapshots
when a snapshot is closed:
drop ref to cloned value files, deleting on the last one (or maybe they're anonymous to begin with, unlinked after the clone completes)
when evicting:
open deferred write transaction on manifest
while manifest page_count*page_size + sum(value_length) from keys >= capacity:
* delete least recently used item
how to do a singleflight fetch for a missing item:
* open manifest
* see a key is in an undesired state
* write a tag with an timestamp of when a fetch was started
* unlock manifest
* perform the fetch
* do a write, and clear the fetch state
advantages:
* you can bring your own files to the cache in their entirety and then have them punched out by the implementation as they decay in usefulness.