Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: chrome/common/extensions/docs/server2/memcache_file_system.py

Issue 10829348: Extensions Docs Server: Large performance increase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes and ObjectStore Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 5 from file_system import FileSystem, StatInfo, FileNotFoundError
6 from future import Future 6 from future import Future
7 import appengine_memcache as memcache 7 import object_store
8
9 class _AsyncUncachedFuture(object):
10 def __init__(self, uncached, current_result, file_system, object_store):
11 self._uncached = uncached
12 self._current_result = current_result
13 self._file_system = file_system
14 self._object_store = object_store
15
16 def Get(self):
17 mapping = {}
18 new_items = self._uncached.Get()
19 for item in new_items:
20 version = self._file_system.Stat(item).version
21 mapping[item] = (new_items[item], version)
22 self._current_result[item] = new_items[item]
23 self._object_store.SetMulti(mapping, object_store.FILE_SYSTEM_READ, time=0)
24 return self._current_result
8 25
9 class MemcacheFileSystem(FileSystem): 26 class MemcacheFileSystem(FileSystem):
10 """FileSystem implementation which memcaches the results of Read. 27 """FileSystem implementation which memcaches the results of Read.
11 """ 28 """
12 def __init__(self, file_system, memcache): 29 def __init__(self, file_system, object_store):
13 self._file_system = file_system 30 self._file_system = file_system
14 self._memcache = memcache 31 self._object_store = object_store
15 32
16 def Stat(self, path): 33 def Stat(self, path, stats=None):
17 """Stats the directory given, or if a file is given, stats the files parent 34 """Stats the directory given, or if a file is given, stats the files parent
18 directory to get info about the file. 35 directory to get info about the file.
19 """ 36 """
20 version = self._memcache.Get(path, memcache.MEMCACHE_FILE_SYSTEM_STAT) 37 # TODO(kalman): store the whole stat info, not just the version.
21 if version is None: 38 version = self._object_store.Get(path, object_store.FILE_SYSTEM_STAT)
22 stat_info = self._file_system.Stat(path) 39 if version is not None:
23 self._memcache.Set(path, 40 return StatInfo(version)
24 stat_info.version, 41
25 memcache.MEMCACHE_FILE_SYSTEM_STAT) 42 # Always stat the parent directory, since it will have the stat of the child
26 if stat_info.child_versions is not None: 43 # anyway, and this gives us an entire directory's stat info at once.
27 for child_path, child_version in stat_info.child_versions.iteritems(): 44 if path.endswith('/'):
28 self._memcache.Set(path.rsplit('/', 1)[0] + '/' + child_path, 45 dir_path = path
29 child_version,
30 memcache.MEMCACHE_FILE_SYSTEM_STAT)
31 else: 46 else:
32 stat_info = self.StatInfo(version) 47 dir_path = path.rsplit('/', 1)[0] + '/'
33 return stat_info 48
49 dir_stat = self._file_system.Stat(dir_path)
50 if path == dir_path:
51 version = dir_stat.version
52 else:
53 version = dir_stat.child_versions.get(path.split('/')[-1], None)
54 # TODO(cduvall): IDL APIs are restatting every load because this exception
55 # is thrown so they never get cached.
not at google - send to devlin 2012/08/21 00:30:11 oh, that seems bad. Is that because it's looking f
cduvall 2012/08/21 01:33:33 Yep, its only one fetch so its not a huge deal, bu
56 if version is None:
57 raise FileNotFoundError(path)
58 mapping = { path: version }
59
60 for child_path, child_version in dir_stat.child_versions.iteritems():
61 child_path = dir_path + child_path
62 mapping[child_path] = child_version
63 self._object_store.SetMulti(mapping, object_store.FILE_SYSTEM_STAT)
64 return StatInfo(version)
34 65
35 def Read(self, paths, binary=False): 66 def Read(self, paths, binary=False):
36 """Reads a list of files. If a file is in memcache and it is not out of 67 """Reads a list of files. If a file is in memcache and it is not out of
37 date, it is returned. Otherwise, the file is retrieved from the file system. 68 date, it is returned. Otherwise, the file is retrieved from the file system.
38 """ 69 """
39 result = {} 70 result = {}
40 uncached = [] 71 uncached = []
41 for path in paths: 72 results = self._object_store.GetMulti(paths,
42 cached_result = self._memcache.Get(path, 73 object_store.FILE_SYSTEM_READ,
43 memcache.MEMCACHE_FILE_SYSTEM_READ) 74 time=0).Get()
75 result_values = [x[1] for x in sorted(results.iteritems())]
76 stats = self._object_store.GetMulti(paths,
77 object_store.FILE_SYSTEM_STAT).Get()
78 stat_values = [x[1] for x in sorted(stats.iteritems())]
79 for path, cached_result, stat in zip(sorted(paths),
80 result_values,
81 stat_values):
44 if cached_result is None: 82 if cached_result is None:
45 uncached.append(path) 83 uncached.append(path)
46 continue 84 continue
47 data, version = cached_result 85 data, version = cached_result
48 if self.Stat(path).version != version: 86 # TODO(cduvall): Make this use a multi stat.
49 self._memcache.Delete(path, memcache.MEMCACHE_FILE_SYSTEM_READ) 87 if stat is None:
88 stat = self.Stat(path).version
89 if stat != version:
90 self._object_store.Delete(path, object_store.FILE_SYSTEM_READ)
50 uncached.append(path) 91 uncached.append(path)
51 continue 92 continue
52 result[path] = data 93 result[path] = data
53 if uncached: 94
54 # TODO(cduvall): if there are uncached items we should return an 95 if not uncached:
55 # asynchronous future. http://crbug.com/142013 96 return Future(value=result)
56 new_items = self._file_system.Read(uncached, binary=binary).Get() 97 return Future(delegate=_AsyncUncachedFuture(
57 for item in new_items: 98 self._file_system.Read(uncached, binary=binary),
58 version = self.Stat(item).version 99 result,
59 value = new_items[item] 100 self,
60 # Cache this file forever. 101 self._object_store))
61 self._memcache.Set(item,
62 (value, version),
63 memcache.MEMCACHE_FILE_SYSTEM_READ,
64 time=0)
65 result[item] = value
66 return Future(value=result)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698