Support part 2/3 for the Memo problem
Bound the size of the memo by creating a BoundedQueue. Whenever we add elements to the BoundedQueue, we remove the oldest elements. We use the BoundedQueue to control the size of our dictionary that we're using to store our key-value pairs.
This commit is contained in:
parent
ec7c8516f7
commit
a8b3a2d3c0
1 changed files with 64 additions and 4 deletions
|
@ -1,18 +1,78 @@
|
|||
import time
|
||||
import random
|
||||
from collections import deque
|
||||
|
||||
memo = {}
|
||||
|
||||
class BoundedQueue(object):
|
||||
def __init__(self, size=0):
|
||||
"""
|
||||
Returns a queue of elements that will never exceed `size`
|
||||
members. BoundedQueue evicts the oldest elements from itself before
|
||||
adding new elements.
|
||||
"""
|
||||
self.xs = deque([None] * size)
|
||||
|
||||
def add(self, x):
|
||||
"""
|
||||
Add element `x` to the end of the queue. Evict the oldest element from
|
||||
the queue.
|
||||
"""
|
||||
evicted = None
|
||||
if self.xs:
|
||||
evicted = self.xs.popleft()
|
||||
self.xs.append(x)
|
||||
return evicted
|
||||
|
||||
|
||||
class Memo(object):
|
||||
def __init__(self, size=1):
|
||||
"""
|
||||
Create a key-value data-structure that will never exceed `size`
|
||||
members. Memo evicts the oldest elements from itself before adding
|
||||
inserting new key-value pairs.
|
||||
"""
|
||||
if size <= 0:
|
||||
raise Exception("We do not support an empty memo")
|
||||
self.xs = {}
|
||||
self.q = BoundedQueue(size=size)
|
||||
|
||||
def contains(self, k):
|
||||
"""
|
||||
Return true if key `k` exists in the Memo.
|
||||
"""
|
||||
return k in self.xs
|
||||
|
||||
def get(self, k):
|
||||
"""
|
||||
Return the memoized item at key `k`.
|
||||
"""
|
||||
return self.xs[k]
|
||||
|
||||
def set(self, k, v):
|
||||
"""
|
||||
Memoize value `v` at key `k`.
|
||||
"""
|
||||
evicted = self.q.add(k)
|
||||
if evicted != None:
|
||||
del self.xs[evicted]
|
||||
self.xs[k] = v
|
||||
|
||||
|
||||
memo = Memo(size=3)
|
||||
|
||||
|
||||
def f(x):
|
||||
if x in memo:
|
||||
"""
|
||||
Compute some mysterious, expensive function.
|
||||
"""
|
||||
if memo.contains(x):
|
||||
print("Hit.\t\tf({})".format(x))
|
||||
return memo[x]
|
||||
return memo.get(x)
|
||||
else:
|
||||
print("Computing...\tf({})".format(x))
|
||||
time.sleep(0.25)
|
||||
res = random.randint(0, 10)
|
||||
memo[x] = res
|
||||
memo.set(x, res)
|
||||
return res
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue