class_docstr: Implements a pseudo-LRU algorithm (CLOCK) with expiration times
  
  The Clock algorithm is not kept strictly to improve performance, e.g. to
  allow get() and invalidate() to work without acquiring the lock.
class_docstr_tok: ["Implements","a","pseudo-LRU","algorithm","(","CLOCK",")","with","expiration","times","The","Clock","algorithm","is","not","kept","strictly","to","improve","performance",",","e.g",".","to","allow","get","(",")","and","invalidate","(",")","to","work","without","acquiring","the","lock","."]
docstr: Return value for key. If not in cache or expired, return default
docstr_tok: ["Return","value","for","key",".","If","not","in","cache","or","expired",",","return","default"]
code: def get(self, key, default=None):
      """Return value for key. If not in cache or expired, return default"""
      self.lookups += 1
      try:
          pos, val, expires = self._data[key]
      except KeyError:
          self.misses += 1
          return default
      if expires > time.time():
          # cache entry still valid
          self.hits += 1
          self.clock_refs[pos] = True
          return val
      else:
          # cache entry has expired. Make sure the space in the cache can
          # be recycled soon.
          self.misses += 1
          self.clock_refs[pos] = False
          return default
  
imports: from abc import abstractmethod
  from abc import ABCMeta
  import threading
  import time
  import uuid
  import inspect
label_desc: Use image node_id 3 for calling the ExpiringLRUCache obj's underlying member method code with example usage: obj.get(key, default) and returns: val, default, default