from threading import Lock
import time

class Cache(dict):

    def __init__(self, ttl=10):
        self._ttl = ttl
        self._added = {}
        self._lock = {}

    def lock(self, key):
        if key not in self._lock:
            self._lock[key] = Lock()
            self._lock[key].acquire()

    def get(self, key):
        now = time.time()
        for k, value in list(self._added.items()):
            if value < now:
                self._added.pop(k, None)
                self.pop(k, None)
                self._lock.pop(k, None)
        if key in self._lock:
            self._lock[key].acquire()
        return dict.get(self, key)

    def set(self, key, value, ttl=None):
        ttl = ttl or self._ttl
        self._added[key] = time.time() + ttl
        dict.__setitem__(self, key, value)
        q = self._lock.pop(key, None)
        if q:
            q.release()

    def delete(self, key):
        if key in self._added:
            del self._added[key]
            del self[key]

    def clear(self, prefix):
        for key in list(self):
            if key.startswith(prefix):
                self.delete(key)