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 time
|
||||||
import random
|
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):
|
def f(x):
|
||||||
if x in memo:
|
"""
|
||||||
|
Compute some mysterious, expensive function.
|
||||||
|
"""
|
||||||
|
if memo.contains(x):
|
||||||
print("Hit.\t\tf({})".format(x))
|
print("Hit.\t\tf({})".format(x))
|
||||||
return memo[x]
|
return memo.get(x)
|
||||||
else:
|
else:
|
||||||
print("Computing...\tf({})".format(x))
|
print("Computing...\tf({})".format(x))
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
res = random.randint(0, 10)
|
res = random.randint(0, 10)
|
||||||
memo[x] = res
|
memo.set(x, res)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue