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

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

 

class ContentCache(object): 

 

def __init__(self): 

self._entries = {} 

self._accessor_ticks = {} 

 

def advance_accessor(self, accessor): 

if accessor not in self._accessor_ticks: 

self._accessor_ticks[accessor] = 0 

 

ta = self._accessor_ticks[accessor] 

 

delete = [] 

for path_segment, entry in self._entries.items(): 

t = entry[2].get(accessor, ta) 

if t < ta: 

del entry[2][accessor] 

if not entry[2]: 

delete.append(path_segment) 

 

for path_segment in delete: 

del self._entries[path_segment] 

 

self._accessor_ticks[accessor] += 1 

 

def clear_accessor(self, accessor): 

delete = [] 

for path_segment, entry in self._entries.items(): 

del entry[2][accessor] 

if not entry[2]: 

delete.append(path_segment) 

 

for path_segment in delete: 

del self._entries[path_segment] 

 

del self._accessor_ticks[accessor] 

 

def clear(self): 

self._entries = {} 

self._accessor_ticks = {} 

 

def has(self, nut): 

path, segment, element, nut_mtime = nut.key 

 

try: 

cache_mtime = self._entries[path, segment][0] 

except KeyError: 

return False 

 

return cache_mtime == nut_mtime 

 

def get(self, nut, accessor='default'): 

path, segment, element, mtime = nut.key 

entry = self._entries[path, segment] 

 

if accessor not in self._accessor_ticks: 

self._accessor_ticks[accessor] = 0 

 

entry[2][accessor] = self._accessor_ticks[accessor] 

 

return entry[1][element] 

 

def _prune_outdated(self, path, segment, nut_mtime): 

try: 

cache_mtime = self._entries[path, segment][0] 

except KeyError: 

return 

 

if cache_mtime != nut_mtime: 

del self._entries[path, segment] 

 

def put(self, nut): 

path, segment, element, mtime = nut.key 

self._prune_outdated(path, segment, nut.file_mtime) 

 

if (path, segment) not in self._entries: 

self._entries[path, segment] = nut.file_mtime, {}, {} 

 

self._entries[path, segment][1][element] = nut.content