Skip to content

Commit ff1d330

Browse files
authored
Give access to the paths without generating the cache. (#80)
1 parent 868f074 commit ff1d330

File tree

2 files changed

+52
-16
lines changed

2 files changed

+52
-16
lines changed

src/cache.toit

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ Typically, caches are stored in the user's home: \$(HOME)/.cache, but users can
2323
2424
To simplify testing, the environment variable '<app-name>_CACHE_DIR' can be used to
2525
override the cache directory.
26+
27+
This library is thread-safe. The library uses atomic moves to
28+
guarantee that cache entries are always complete. If two processes
29+
try to write the same cache entry then the first one to finish wins
30+
and the second one is ignored.
31+
32+
The cache has no way to update an existing entry. If you want to
33+
update an entry, you must remove it first.
2634
*/
2735

2836
/**
@@ -77,6 +85,15 @@ class Cache:
7785
key-path := key-path_ key
7886
return file.is-file key-path or file.is-directory key-path
7987

88+
/**
89+
Returns a path to the cache entry with the given $key.
90+
91+
If the cache entry doesn't exist yet, then the returned string
92+
points to a non-existing file.
93+
*/
94+
get-file-path key/string -> string:
95+
return key-path_ key
96+
8097
/**
8198
Variant of $(get key [block]).
8299
@@ -113,6 +130,15 @@ class Cache:
113130
key-path := get-file-path key block
114131
return file.read-contents key-path
115132

133+
/**
134+
Returns the path to the directory item with the given $key.
135+
136+
If the cache entry doesn't exist yet, then the returned string
137+
points to a non-existing directory.
138+
*/
139+
get-directory-path key/string -> string:
140+
return key-path_ key
141+
116142
/**
117143
Returns the path to the cached directory item with the given $key.
118144
@@ -221,39 +247,39 @@ interface FileStore:
221247
Calls the given $block with the path as argument.
222248
The temporary directory is deleted after the block returns.
223249
*/
224-
with-tmp-directory [block]
250+
with-tmp-directory [block] -> none
225251

226252
/**
227253
Saves the given $bytes as the content of $key.
228254
229255
If the key already exists, the generated content is dropped.
230256
This can happen if two processes try to access the cache at the same time.
231257
*/
232-
save bytes/ByteArray
258+
save bytes/io.Data -> none
233259

234260
/**
235261
Calls the given $block with a $io.Writer.
236262
237263
The $block must write its chunks to the writer.
238264
The writer is closed after the block returns.
239265
*/
240-
save-via-writer [block]
266+
save-via-writer [block] -> none
241267

242268
/**
243269
Copies the content of $path to the cache under $key.
244270
245271
If the key already exists, the generated content is dropped.
246272
This can happen if two processes try to access the cache at the same time.
247273
*/
248-
copy path/string
274+
copy path/string -> none
249275

250276
/**
251277
Moves the file at $path to the cache under $key.
252278
253279
If the key already exists, the generated content is dropped.
254280
This can happen if two processes try to access the cache at the same time.
255281
*/
256-
move path/string
282+
move path/string -> none
257283

258284
// TODO(florian): add "download" method.
259285
// download url/string --compressed/bool=false --path/string="":
@@ -275,23 +301,23 @@ interface DirectoryStore:
275301
Calls the given $block with the path as argument.
276302
The temporary directory is deleted after the block returns.
277303
*/
278-
with-tmp-directory [block]
304+
with-tmp-directory [block] -> none
279305

280306
/**
281307
Copies the content of the directory $path to the cache under $key.
282308
283309
If the key already exists, the generated content is dropped.
284310
This can happen if two processes try to access the cache at the same time.
285311
*/
286-
copy path/string
312+
copy path/string -> none
287313

288314
/**
289315
Moves the directory at $path to the cache under $key.
290316
291317
If the key already exists, the generated content is dropped.
292318
This can happen if two processes try to access the cache at the same time.
293319
*/
294-
move path/string
320+
move path/string -> none
295321

296322
// TODO(florian): add "download" method.
297323
// Must be a tar, tar.gz, tgz, or zip.
@@ -315,7 +341,7 @@ class FileStore_ implements FileStore:
315341
Calls the given $block with the path as argument.
316342
The temporary directory is deleted after the block returns.
317343
*/
318-
with-tmp-directory [block]:
344+
with-tmp-directory [block] -> none:
319345
cache_.with-tmp-directory_ block
320346

321347
/**
@@ -324,7 +350,7 @@ class FileStore_ implements FileStore:
324350
If the key already exists, the generated content is dropped.
325351
This can happen if two processes try to access the cache at the same time.
326352
*/
327-
save bytes/ByteArray:
353+
save bytes/io.Data -> none:
328354
store_: | file-path/string |
329355
file.write-contents bytes --path=file-path
330356

@@ -334,7 +360,7 @@ class FileStore_ implements FileStore:
334360
The $block must write its chunks to the writer.
335361
The writer is closed after the block returns.
336362
*/
337-
save-via-writer [block]:
363+
save-via-writer [block] -> none:
338364
store_: | file-path/string |
339365
stream := file.Stream.for-write file-path
340366
try:
@@ -348,7 +374,7 @@ class FileStore_ implements FileStore:
348374
If the key already exists, the generated content is dropped.
349375
This can happen if two processes try to access the cache at the same time.
350376
*/
351-
copy path/string:
377+
copy path/string -> none:
352378
store_: | file-path/string |
353379
copy-file_ --source=path --target=file-path
354380

@@ -358,7 +384,7 @@ class FileStore_ implements FileStore:
358384
If the key already exists, the generated content is dropped.
359385
This can happen if two processes try to access the cache at the same time.
360386
*/
361-
move path/string:
387+
move path/string -> none:
362388
if has-stored_: throw "Already saved content for key: $key"
363389
if is-closed_: throw "FileStore is closed"
364390

@@ -402,7 +428,7 @@ class DirectoryStore_ implements DirectoryStore:
402428
Calls the given $block with the path as argument.
403429
The temporary directory is deleted after the block returns.
404430
*/
405-
with-tmp-directory [block]:
431+
with-tmp-directory [block] -> none:
406432
cache_.with-tmp-directory_ block
407433

408434
/**
@@ -411,7 +437,7 @@ class DirectoryStore_ implements DirectoryStore:
411437
If the key already exists, the generated content is dropped.
412438
This can happen if two processes try to access the cache at the same time.
413439
*/
414-
copy path/string:
440+
copy path/string -> none:
415441
store_: | dir-path/string |
416442
copy-directory --source=path --target=dir-path
417443

@@ -421,7 +447,7 @@ class DirectoryStore_ implements DirectoryStore:
421447
If the key already exists, the generated content is dropped.
422448
This can happen if two processes try to access the cache at the same time.
423449
*/
424-
move path/string:
450+
move path/string -> none:
425451
store_: | dir-path/string |
426452
// TODO(florian): we should be able to test whether the rename should succeed.
427453
exception := catch: file.rename path dir-path

tests/cache_test.toit

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ test-file-cache:
3535

3636
key2 := "dir/nested/many/levels/key2"
3737
expect-not (c.contains key2)
38+
key2-path := c.get-file-path key2
39+
expect-equals "$cache-dir/$key2" key2-path
40+
expect-not (file.is-file key2-path)
41+
3842
value2 := c.get key2: | store/cache.FileStore |
3943
store.save #[4, 5, 6]
4044
expect-equals value2 #[4, 5, 6]
@@ -43,6 +47,9 @@ test-file-cache:
4347
throw "Should not be called"
4448
expect-equals value2 #[4, 5, 6]
4549

50+
path = c.get-file-path key2
51+
expect-equals "$cache-dir/$key2" path
52+
4653
path2 := c.get-file-path key2: | store |
4754
throw "Should not be called"
4855
expect-equals path2 "$cache-dir/$key2"
@@ -56,6 +63,9 @@ test-file-cache:
5663
dir-entries.add entry
5764

5865
key3 := "dir/key3"
66+
path = c.get-directory-path key3
67+
expect-equals "$cache-dir/$key3" path
68+
5969
expect-not (c.contains key3)
6070
value3 := c.get key3: | store/cache.FileStore |
6171
store.with-tmp-directory: | tmp-dir |

0 commit comments

Comments
 (0)