9948de8fe9c010d6b68fe6b09977ea2e77a0cdaf
[tiramisu.git] / tiramisu / storage / util.py
1 # -*- coding: utf-8 -*-
2 "utils used by storage"
3 # Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as published by the
7 # Free Software Foundation, either version 3 of the License, or (at your
8 # option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 # ____________________________________________________________
18 from ..setting import owners
19
20
21 class SerializeObject(object):
22     def __getstate__(self):
23         ret = {}
24         for key in dir(self):
25             if not key.startswith('__'):
26                 ret[key] = getattr(self, key)
27         return ret
28
29
30 class Cache(object):
31     __slots__ = ('_cache', '_storage')
32     key_is_path = False
33
34     def __init__(self, storage):
35         self._cache = {}
36         self._storage = storage
37
38     def __getstate__(self):
39         slots = set()
40         for subclass in self.__class__.__mro__:
41             if subclass is not object:
42                 slots.update(subclass.__slots__)
43         slots -= frozenset(['__weakref__', '_storage'])
44         states = {}
45         for slot in slots:
46             try:
47                 value = getattr(self, slot)
48                 #value has owners object, need 'str()' it
49                 if slot == '_values':
50                     _value = []
51                     _value.append(value[0])
52                     _value.append(value[1])
53                     str_owner = []
54                     _value.append(value[2])
55                     for owner in value[3]:
56                         if isinstance(owner, list):
57                             str_owners = []
58                             for subowner in owner:
59                                 str_owners.append(str(subowner))
60                             str_owner.append(str_owners)
61                         else:
62                             str_owner.append(str(owner))
63                     _value.append(str_owner)
64                     states[slot] = _value
65                 else:
66                     states[slot] = value
67             except AttributeError:
68                 pass
69         return states
70
71     def __setstate__(self, states):
72         def convert_owner(owner):
73             try:
74                 owner = getattr(owners, owner)
75             except AttributeError:
76                 owners.addowner(owner)
77                 owner = getattr(owners, owner)
78             return owner
79
80         for key, value in states.items():
81             #value has owners object, need to reconstruct it
82             if key == '_values':
83                 _value = []
84                 _value.append(value[0])
85                 _value.append(value[1])
86                 _value.append(value[2])
87                 obj_owner = []
88                 for owner in value[3]:
89                     if isinstance(owner, list):
90                         obj_owners = []
91                         for subowner in owner:
92                             obj_owners.append(convert_owner(subowner))
93                         obj_owner.append(tuple(obj_owners))
94                     else:
95                         obj_owner.append(convert_owner(owner))
96                 _value.append(tuple(obj_owner))
97                 value = tuple(_value)
98             setattr(self, key, value)
99
100     def setcache(self, path, val, time, index):
101         self._cache.setdefault(path, {})[index] = (val, time)
102
103     def getcache(self, path, exp, index):
104         value, created = self._cache[path][index]
105         if created is None or exp <= created:
106             return True, value
107         return False, None
108
109     def hascache(self, path, index):
110         """ path is in the cache
111
112         :param path: the path's option
113         """
114         return path in self._cache and index in self._cache[path]
115
116     def reset_expired_cache(self, exp):
117         cache_keys = list(self._cache.keys())
118         for key in cache_keys:
119             key_cache_keys = list(self._cache[key].keys())
120             for index in key_cache_keys:
121                 val, created = self._cache[key][index]
122                 if created is not None and exp > created:
123                     del(self._cache[key][index])
124                     if self._cache[key] == {}:
125                         del(self._cache[key])
126
127     def reset_all_cache(self):
128         "empty the cache"
129         self._cache.clear()
130
131     def get_cached(self, context):
132         """return all values in a dictionary
133         example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
134         """
135         return self._cache