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
48
49
50
51
52
53
54
55
56
|
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from file_system import FileSystem
from future import Future
import appengine_memcache as memcache
class MemcacheFileSystem(FileSystem):
"""FileSystem implementation which memcaches the results of Read.
"""
def __init__(self, file_system, memcache):
self._file_system = file_system
self._memcache = memcache
def Stat(self, path):
"""Stats the directory given, or if a file is given, the file's parent
directory.
"""
version = self._memcache.Get(path, memcache.MEMCACHE_FILE_SYSTEM_STAT)
if version is None:
stat_info = self._file_system.Stat(path)
self._memcache.Set(path,
stat_info.version,
memcache.MEMCACHE_FILE_SYSTEM_STAT)
else:
stat_info = self.StatInfo(version)
return stat_info
def Read(self, paths, binary=False):
"""Reads a list of files. If a file is in memcache and it is not out of
date, it is returned. Otherwise, the file is retrieved from the file system.
"""
result = {}
uncached = []
for path in paths:
cached_result = self._memcache.Get(path,
memcache.MEMCACHE_FILE_SYSTEM_READ)
if cached_result is None:
uncached.append(path)
continue
data, version = cached_result
if self.Stat(path).version > version:
self._memcache.Delete(path, memcache.MEMCACHE_FILE_SYSTEM_READ)
uncached.append(path)
continue
result[path] = data
new_items = self._file_system.Read(uncached, binary=binary).Get()
for item in new_items:
version = self.Stat(item).version
value = new_items[item]
self._memcache.Set(item,
(value, version),
memcache.MEMCACHE_FILE_SYSTEM_READ)
result[item] = value
return Future(value=result)
|