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…
	
	Add table
		Add a link
		
	
		Reference in a new issue