OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from file_system import FileSystem, StatInfo, FileNotFoundError | 5 from file_system import FileSystem, StatInfo, FileNotFoundError |
6 from future import Future | 6 from future import Future |
7 | 7 |
| 8 from object_store_creator import ObjectStoreCreator |
| 9 |
8 class _AsyncUncachedFuture(object): | 10 class _AsyncUncachedFuture(object): |
9 def __init__(self, | 11 def __init__(self, |
10 uncached_read_futures, | 12 uncached_read_futures, |
11 stats_for_uncached, | 13 stats_for_uncached, |
12 current_results, | 14 current_results, |
13 file_system, | 15 file_system, |
14 object_store): | 16 object_store): |
15 self._uncached_read_futures = uncached_read_futures | 17 self._uncached_read_futures = uncached_read_futures |
16 self._stats_for_uncached = stats_for_uncached | 18 self._stats_for_uncached = stats_for_uncached |
17 self._current_results = current_results | 19 self._current_results = current_results |
18 self._file_system = file_system | 20 self._file_system = file_system |
19 self._object_store = object_store | 21 self._object_store = object_store |
20 | 22 |
21 def Get(self): | 23 def Get(self): |
22 new_results = self._uncached_read_futures.Get() | 24 new_results = self._uncached_read_futures.Get() |
23 # Update the cached data in the object store. This is a path -> (read, | 25 # Update the cached data in the object store. This is a path -> (read, |
24 # version) mapping. | 26 # version) mapping. |
25 self._object_store.SetMulti(dict( | 27 self._object_store.SetMulti(dict( |
26 (path, (new_result, self._stats_for_uncached[path].version)) | 28 (path, (new_result, self._stats_for_uncached[path].version)) |
27 for path, new_result in new_results.iteritems())) | 29 for path, new_result in new_results.iteritems())) |
28 new_results.update(self._current_results) | 30 new_results.update(self._current_results) |
29 return new_results | 31 return new_results |
30 | 32 |
31 class CachingFileSystem(FileSystem): | 33 class CachingFileSystem(FileSystem): |
32 '''FileSystem which implements a caching layer on top of |file_system|. It's | 34 '''FileSystem which implements a caching layer on top of |file_system|. It's |
33 smart, using Stat() to decided whether to skip Read()ing from |file_system|, | 35 smart, using Stat() to decided whether to skip Read()ing from |file_system|, |
34 and only Stat()ing directories never files. | 36 and only Stat()ing directories never files. |
35 | |
36 Specify |use_existing_values| to continue using whatever has been cached in | |
37 the object stores. By default, the data in the stores is assumed to be stale | |
38 (althought consistent). Using existing values is useful for live instances | |
39 that don't want to touch the file system; not using them is good for the | |
40 cron jobs, where we want to refresh the data. | |
41 ''' | 37 ''' |
42 def __init__(self, | 38 def __init__(self, file_system, object_store_creator_factory): |
43 file_system, | |
44 object_store_creator_factory, | |
45 use_existing_values=False): | |
46 self._file_system = file_system | 39 self._file_system = file_system |
47 def create_object_store(category): | 40 def create_object_store(category, start_configuration=None): |
48 return (object_store_creator_factory.Create(CachingFileSystem) | 41 return (object_store_creator_factory.Create(CachingFileSystem) |
49 .Create(category='%s/%s' % (file_system.GetName(), category), | 42 .Create(category='%s/%s' % (file_system.GetName(), category), |
50 # By Stat()ing from scratch we'll end up not using the | 43 start_configuration=start_configuration)) |
51 # existing values, but also not doing unnecessary Read()s if | 44 # Use the existing start configuation. |
52 # the files haven't changed from last time. | |
53 start_empty=(not use_existing_values and category == 'stat'))) | |
54 self._stat_object_store = create_object_store('stat') | 45 self._stat_object_store = create_object_store('stat') |
55 self._read_object_store = create_object_store('read') | 46 # Force START_POPULATED for the read stores since if Stat is empty we're |
56 self._read_binary_object_store = create_object_store('read-binary') | 47 # effectively starting empty - but won't be doing unnecessary Read()s if |
| 48 # the files haven't changed from last time. |
| 49 self._read_object_store = create_object_store( |
| 50 'read', |
| 51 start_configuration=ObjectStoreCreator.START_POPULATED) |
| 52 self._read_binary_object_store = create_object_store( |
| 53 'read-binary', |
| 54 start_configuration=ObjectStoreCreator.START_POPULATED) |
57 | 55 |
58 def Stat(self, path): | 56 def Stat(self, path): |
59 '''Stats the directory given, or if a file is given, stats the file's parent | 57 '''Stats the directory given, or if a file is given, stats the file's parent |
60 directory to get info about the file. | 58 directory to get info about the file. |
61 ''' | 59 ''' |
62 # Always stat the parent directory, since it will have the stat of the child | 60 # Always stat the parent directory, since it will have the stat of the child |
63 # anyway, and this gives us an entire directory's stat info at once. | 61 # anyway, and this gives us an entire directory's stat info at once. |
64 if path.endswith('/'): | 62 if path.endswith('/'): |
65 dir_path = path | 63 dir_path = path |
66 else: | 64 else: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 109 |
112 if not uncached: | 110 if not uncached: |
113 return Future(value=results) | 111 return Future(value=results) |
114 | 112 |
115 return Future(delegate=_AsyncUncachedFuture( | 113 return Future(delegate=_AsyncUncachedFuture( |
116 self._file_system.Read(uncached.keys(), binary=binary), | 114 self._file_system.Read(uncached.keys(), binary=binary), |
117 uncached, | 115 uncached, |
118 results, | 116 results, |
119 self, | 117 self, |
120 read_object_store)) | 118 read_object_store)) |
OLD | NEW |