Package pyxmpp :: Module expdict
[hide private]

Source Code for Module pyxmpp.expdict

  1  # 
  2  # (C) Copyright 2003-2010 Jacek Konieczny <jajcus@jajcus.net> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU Lesser General Public License Version 
  6  # 2.1 as published by the Free Software Foundation. 
  7  # 
  8  # This program is distributed in the hope that it will be useful, 
  9  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 11  # GNU Lesser General Public License for more details. 
 12  # 
 13  # You should have received a copy of the GNU Lesser General Public 
 14  # License along with this program; if not, write to the Free Software 
 15  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 16  # 
 17   
 18  """Dictionary with item expiration.""" 
 19   
 20  __docformat__="restructuredtext en" 
 21   
 22  import time 
 23  import threading 
 24   
 25  __all__ = ['ExpiringDictionary'] 
 26   
 27  sentinel = object() 
 28   
29 -class ExpiringDictionary(dict):
30 """An extension to standard Python dictionary objects which implements item 31 expiration. 32 33 Each item in ExpiringDictionary has its expiration time assigned, after 34 which the item is removed from the mapping. 35 36 :Ivariables: 37 - `_timeouts`: a dictionary with timeout values and timeout callback for 38 stored objects. 39 - `_default_timeout`: the default timeout value (in seconds from now). 40 - `_lock`: access synchronization lock. 41 :Types: 42 - `_timeouts`: `dict` 43 - `_default_timeout`: `int` 44 - `_lock`: `threading.RLock`""" 45 46 __slots__=['_timeouts','_default_timeout','_lock'] 47
48 - def __init__(self,default_timeout=300):
49 """Initialize an `ExpiringDictionary` object. 50 51 :Parameters: 52 - `default_timeout`: default timeout value for stored objects. 53 :Types: 54 - `default_timeout`: `int`""" 55 dict.__init__(self) 56 self._timeouts={} 57 self._default_timeout=default_timeout 58 self._lock=threading.RLock()
59
60 - def __delitem__(self,key):
61 self._lock.acquire() 62 try: 63 del self._timeouts[key] 64 return dict.__delitem__(self,key) 65 finally: 66 self._lock.release()
67
68 - def __getitem__(self,key):
69 self._lock.acquire() 70 try: 71 self._expire_item(key) 72 return dict.__getitem__(self,key) 73 finally: 74 self._lock.release()
75
76 - def pop(self,key,default=sentinel):
77 self._lock.acquire() 78 try: 79 self._expire_item(key) 80 del self._timeouts[key] 81 if default is not sentinel: 82 return dict.pop(self,key,default) 83 else: 84 return dict.pop(self,key) 85 finally: 86 self._lock.release()
87
88 - def __setitem__(self,key,value):
89 return self.set_item(key,value)
90
91 - def set_item(self,key,value,timeout=None,timeout_callback=None):
92 """Set item of the dictionary. 93 94 :Parameters: 95 - `key`: the key. 96 - `value`: the object to store. 97 - `timeout`: timeout value for the object (in seconds from now). 98 - `timeout_callback`: function to be called when the item expires. 99 The callback should accept none, one (the key) or two (the key 100 and the value) arguments. 101 :Types: 102 - `key`: any hashable value 103 - `value`: any python object 104 - `timeout`: `int` 105 - `timeout_callback`: callable""" 106 self._lock.acquire() 107 try: 108 if not timeout: 109 timeout=self._default_timeout 110 self._timeouts[key]=(time.time()+timeout,timeout_callback) 111 return dict.__setitem__(self,key,value) 112 finally: 113 self._lock.release()
114
115 - def expire(self):
116 """Do the expiration of dictionary items. 117 118 Remove items that expired by now from the dictionary.""" 119 self._lock.acquire() 120 try: 121 for k in self._timeouts.keys(): 122 self._expire_item(k) 123 finally: 124 self._lock.release()
125
126 - def _expire_item(self,key):
127 """Do the expiration of a dictionary item. 128 129 Remove the item if it has expired by now. 130 131 :Parameters: 132 - `key`: key to the object. 133 :Types: 134 - `key`: any hashable value""" 135 (timeout,callback)=self._timeouts[key] 136 if timeout<=time.time(): 137 item = dict.pop(self, key) 138 del self._timeouts[key] 139 if callback: 140 try: 141 callback(key,item) 142 except TypeError: 143 try: 144 callback(key) 145 except TypeError: 146 callback()
147 148 # vi: sts=4 et sw=4 149