实现线程安全先进先出的dict

# encoding:utf-8

from collections import OrderedDict
from collections import MutableMapping
from threading import RLock

_Null = object()


def iterkeys(d, **kw):
return d.iterkeys(**kw)


def itervalues(d, **kw):
return d.itervalues(**kw)


class RecentlyUsedContainer(MutableMapping):
"""
Provides a thread-safe dict-like container which maintains up to
``maxsize`` keys while throwing away the least-recently-used keys beyond
``maxsize``.

:param maxsize:
Maximum number of recent elements to retain.

:param dispose_func:
Every time an item is evicted from the container,
``dispose_func(value)`` is called. Callback which will get called
"""

ContainerCls = OrderedDict

def __init__(self, maxsize=10, dispose_func=None):
self._maxsize = maxsize
self.dispose_func = dispose_func

self._container = self.ContainerCls()
self.lock = RLock()

def __getitem__(self, key):
# Re-insert the item, moving it to the end of the eviction line.
with self.lock:
item = self._container.pop(key)
self._container[key] = item
return item

def __setitem__(self, key, value):
evicted_value = _Null
with self.lock:
# Possibly evict the existing value of 'key'
evicted_value = self._container.get(key, _Null)
self._container[key] = value

# If we didn't evict an existing value, we might have to evict the
# least recently used item from the beginning of the container.
if len(self._container) > self._maxsize:
_key, evicted_value = self._container.popitem(last=False)

if self.dispose_func and evicted_value is not _Null:
self.dispose_func(evicted_value)

def __delitem__(self, key):
with self.lock:
value = self._container.pop(key)

if self.dispose_func:
self.dispose_func(value)

def __len__(self):
with self.lock:
return len(self._container)

def __iter__(self):
raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')

def clear(self):
with self.lock:
# Copy pointers to all values, then wipe the mapping
values = list(itervalues(self._container))
print values
self._container.clear()

if self.dispose_func:
for value in values:
self.dispose_func(value)

def keys(self):
with self.lock:
return list(iterkeys(self._container))


if __name__ == '__main__':
d = RecentlyUsedContainer()
print(dir(d))
d['key1'] = 'value1'
print d._maxsize
# d['key2'] = 'value2'
# d['key3'] = 'value3'
# d['key4'] = 'value4'
# print d.keys()
# del d['key4']
# d.clear()
# print d.keys()

posted @ 2018-08-10 08:42  tny_leyon  阅读(278)  评论(0编辑  收藏  举报