I\'m writing a software with Python and I need a class to store a set of elements (order is not relevant and not repeated elements), like the Python class set
,
I don't see any reason not to go with multithreading. As it is really easy to implement, with minimum code. Roughly something like this:
import threading
import time
def ttl_set_remove(my_set, item, ttl):
time.sleep(ttl)
my_set.remove(item)
class MySet(set):
def add(self, item, ttl):
set.add(self, item)
t = threading.Thread(target=ttl_set_remove, args=(self, item, ttl))
t.start()
test:
s = MySet()
s.add('a', 20)
s.add('b', 10)
s.add('c', 2)
print(s)
time.sleep(5)
print(s)
>>>
MySet({'c', 'b', 'a'})
MySet({'b', 'a'})
Just an idea (of course, it isn't the best one): Use a dictionary to store the timestamp of each addition plus the concrete timeout for each item. Then, when you want to check if an item is in the set, you have to compare the current time with the value in the dictionary. This way you don't need to start a new thread to remove each item when the timeout is finished (just keep the key in the dictionary, and update it if the item is added again).
With this solution you have to implement __contains__
and __iter__
apart from add
, to make sure 'a' in myset
and iter(myset)
returns consistent results.
import time
class TimedSet(set):
def __init__(self):
self.__table = {}
def add(self, item, timeout=1):
self.__table[item] = time.time() + timeout
set.add(self, item)
def __contains__(self, item):
return time.time() < self.__table.get(item)
def __iter__(self):
for item in set.__iter__(self):
if time.time() < self.__table.get(item):
yield item
And a possible example of usage:
t_set = TimedSet()
t_set.add('a')
time.sleep(0.6)
print 'a' in t_set
time.sleep(0.6)
print 'a' in t_set
t_set.add('x', 0.3)
t_set.add('y', 0.4)
t_set.add('z', 0.5)
time.sleep(0.35)
for item in t_set:
print item