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

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: server is fast 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
6 from future import Future 6 from future import Future
7 import appengine_memcache as memcache 7 import appengine_memcache as memcache
8 8
9 class _AsyncUncachedFuture(object):
10 def __init__(self, uncached, current_result, file_system, memcache):
11 self._uncached = uncached
12 self._current_result = current_result
13 self._file_system = file_system
14 self._memcache = memcache
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._memcache.SetMulti(mapping, memcache.MEMCACHE_FILE_SYSTEM_READ, time=0)
24 return self._current_result
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, memcache):
13 self._file_system = file_system 30 self._file_system = file_system
14 self._memcache = memcache 31 self._memcache = memcache
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 """
37 # TODO(kalman): store the whole stat info, not just the version.
20 version = self._memcache.Get(path, memcache.MEMCACHE_FILE_SYSTEM_STAT) 38 version = self._memcache.Get(path, memcache.MEMCACHE_FILE_SYSTEM_STAT)
21 if version is None: 39 if version is not None:
22 stat_info = self._file_system.Stat(path) 40 return StatInfo(version)
23 self._memcache.Set(path, 41
24 stat_info.version, 42 # Always stat the parent directory, since it will have the stat of the child
25 memcache.MEMCACHE_FILE_SYSTEM_STAT) 43 # anyway, and this gives us an entire directory's stat info at once.
26 if stat_info.child_versions is not None: 44 if path.endswith('/'):
27 for child_path, child_version in stat_info.child_versions.iteritems(): 45 dir_path = path
28 self._memcache.Set(path.rsplit('/', 1)[0] + '/' + child_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 mapping = { path: dir_stat.version }
53
54 for child_path, child_version in dir_stat.child_versions.iteritems():
55 child_path = dir_path + child_path
56 if path == child_path:
57 version = child_version
not at google - send to devlin 2012/08/20 05:27:10 dunno why I wrote it that way. seems better to put
cduvall 2012/08/20 21:28:09 Done.
58 mapping[child_path] = child_version
59 self._memcache.SetMulti(mapping, memcache.MEMCACHE_FILE_SYSTEM_STAT)
60 return StatInfo(version)
34 61
35 def Read(self, paths, binary=False): 62 def Read(self, paths, binary=False):
36 """Reads a list of files. If a file is in memcache and it is not out of 63 """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. 64 date, it is returned. Otherwise, the file is retrieved from the file system.
38 """ 65 """
39 result = {} 66 result = {}
40 uncached = [] 67 uncached = []
41 for path in paths: 68 results = self._memcache.GetMulti(paths,
42 cached_result = self._memcache.Get(path, 69 memcache.MEMCACHE_FILE_SYSTEM_READ,
43 memcache.MEMCACHE_FILE_SYSTEM_READ) 70 time=0).Get()
71 result_values = [x[1] for x in sorted(results.iteritems())]
72 stats = self._memcache.GetMulti(paths,
73 memcache.MEMCACHE_FILE_SYSTEM_STAT).Get()
not at google - send to devlin 2012/08/20 05:27:10 It would be nice if Stat took multiple things, lik
cduvall 2012/08/20 21:28:09 Done.
74 stat_values = [x[1] for x in sorted(stats.iteritems())]
75 for path, cached_result, stat in zip(sorted(paths),
76 result_values,
77 stat_values):
44 if cached_result is None: 78 if cached_result is None:
45 uncached.append(path) 79 uncached.append(path)
46 continue 80 continue
47 data, version = cached_result 81 data, version = cached_result
48 if self.Stat(path).version != version: 82 if stat is None:
83 stat = self.Stat(path).version
84 if stat != version:
49 self._memcache.Delete(path, memcache.MEMCACHE_FILE_SYSTEM_READ) 85 self._memcache.Delete(path, memcache.MEMCACHE_FILE_SYSTEM_READ)
50 uncached.append(path) 86 uncached.append(path)
51 continue 87 continue
52 result[path] = data 88 result[path] = data
53 if uncached: 89
54 # TODO(cduvall): if there are uncached items we should return an 90 if not uncached:
55 # asynchronous future. http://crbug.com/142013 91 return Future(value=result)
56 new_items = self._file_system.Read(uncached, binary=binary).Get() 92 return Future(delegate=_AsyncUncachedFuture(
57 for item in new_items: 93 self._file_system.Read(uncached, binary=binary),
58 version = self.Stat(item).version 94 result,
59 value = new_items[item] 95 self,
60 # Cache this file forever. 96 self._memcache))
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