Question: The ContentItem and Node classes The ContentItem class holds a piece of content and is described below. All methods have been implemented for you except

The ContentItem and Node classes

The ContentItem class holds a piece of content and is described below. All methods have been implemented for you except __hash__. Do not modify the given code.

Attributes

Type

Name

Description

int

cid

Stores the content id.

int

size

Stores the size of the content as a nonnegative integer.

str

header

Information stored by the ContentItem (used for hash function later)

str

content

Information stored by the ContentItem

Special methods

Type

Name

Description

None

__init__(self, cid, size, header, content)

Creates a ContentItem from parameters

int

__hash__(self)

Returns the hash value for this ContentItem

str

__str__(self), __repr__(self)

String representation of this object

bool

__eq__(self, other)

Checks for equality with another object

__hash__(self) (5 pts)

Returns the hash value for this ContentItem (used by the Cache class). For this assignment, let the hash value be equal to the sum of every ASCII value in the header, modulo 3. This is the special method for the built-in method hash(object), for example hash('hello'). Hint: the ord(c)method could be helpful here.

Output

int

An integer between 0 and 2 (inclusive), based on the hash function described above

The Node class has been implemented for you and is described below. Do not modify the given code.

Attributes

Type

Name

Description

ContentItem

value

Stores the value of this Node (always a ContentItem in this case)

Node

previous

Points to the preceding Node in the linked list (defaults to None)

Node

next

Points to the following Node in the linked list (defaults to None)

Special methods

Type

Name

Description

None

__init__(self, content)

Creates a new Node that holds the given ContentItem

str

__str__(self), __repr__(self)

String representation of this object

Section 3: The CacheList class

The CacheList class describes a single cache level in our hierarchy, implemented as a doubly linked list with references to the first and last node in the list (head and tail). Items are moved to the front every time they are added or used, creating an order in the list from most recently used to least recently used. READ the outline for all the methods in this class first, the put method should be the last one to be implemented in this class since it relies on the correctness of the other methods. A portion of your grade in this class comes from your ability to reuse code by calling other methods.

Attributes

Type

Name

Description

Node

head

Points to the first node in the linked list (defaults to None)

Node

tail

Points to the last node in the linked list (defaults to None)

int

maxSize

Maximum size that the CacheList can store

int

remainingSpace

Remaining size that the CacheList can store

int

numItems

The number of items currently in the CacheList

Methods

Type

Name

Description

str

put(self, content, evictionPolicy)

Adds Nodes at the beginning of the list

str

update(self, cid, content)

Updates the content in the list

None

mruEvict(self), lruEvict(self)

Removes the first/last item of the list

str

clear(self)

Removes all items from the list

Special methods

Type

Name

Description

None

__init__(self, size)

Creates a new CacheList with a given maximum size

str

__str__(self), __repr__(self)

String representation of this object

int

__len__(self)

The number of items in the CacheList

bool

__contains__(self, cid)

Determines if a content with cid is in the list

put(self, content, evictionPolicy) (15 pts)

5 pts for addition at the beginning of the list, 10 pts for complete functionality from the HashTable class and evictions

Adds nodes at the beginning of the list and evicts items as necessary to free up space. If the content is larger than the maximum size, do not evict anything. Otherwise, if the content id exists in the list prior the insertion, new content is not added into the list, but the existing content is moved to the beginning of the list. If there is currently not enough space for the content, evict items according to the eviction policy.

Input

ContentItem

content

The content item to add to the list

str

evictionPolicy

The desired eviction policy (either 'lru' or 'mru')

Output

str

'INSERTED: contentItem' if insertion was successful

str

'Insertion not allowed' if content size > maximum size

str

'Content {id} already in cache, insertion not allowed' if id is already present in the list

__contains__(self, cid) (15 pts)

Finds a ContentItem from the list by id, moving the ContentItem to the front of the list if found. This is the special method for the in operator to allow the syntax cid in object.

Input

int

cid

The id to search for in the CacheList

Output

bool

True if the matching ContentItem is in the list, False otherwise

update(self, cid, content) (10 pts)

Updates a ContentItem with a given id in the list. If a match is found, it is moved to the beginning of the list and the old ContentItem is entirely replaced with the new ContentItem. You cannot assume the size of the new content will be the same as the content in the list, thus, you must check that there is enough available space to perform the update. The update is not completed if the change results on exceeding the maxSize of the list, but the match is moved at the beginning of the list.

Input

int

cid

The id to search for in the CacheList

ContentItem

content

The values to update the existing ContentItem with

Output

str

'UPDATED: contentItem' if update was successful

str

'Cache miss!' is returned if no match is found or the update exceeds the maxSize

lruEvict(self) / mruEvict(self) (10 pts each)Removes the last (least recently used) or the first (most recently used) item of the list

Output

None

This function returns nothing.

clear(self) (5 pts)

Removes all items from the list. This method must unlink all nodes from the list

Output

str

'Cleared cache!'

Section 4: The Cache class

The Cache class describes the overall cache, implemented as a hash table. It contains three CacheLists which actually store the ContentItems. Hash values of 0 correspond with the first CacheList (L1), 1 with L2, and 2 with L3.

0

1

2

Level L1

Level L2

Level L3

CacheList(size)

CacheList(size)

CacheList(size)

All methods in the Cache class will call a corresponding method in the CacheList class. For example, the insert method calls the put method from the CacheList class.

Do not change the initialization of the CacheList objects in the starter code. You are not allowed to add any other methods in this class. Your code will not receive credit if you add other methods.

Attributes

Type

Name

Description

list

hierarchy

List with 3 CacheList objects of size (lst_capacity)

int

size

Number of levels in our hierarchy (always set to 3)

Methods

Type

Name

Description

str

insert(self, content, evictionPolicy)

Adds an item into the proper cache list

str

clear(self)

Clears all CacheLists in the hierarchy.

Special methods

Type

Name

Description

None

__init__(self, lst_capacity)

Creates a new Cache with (3) CacheLists of size lst_capacity

str

__str__(self), __repr__(self)

String representation of this object

(various)

__getitem__(self, content)

Gets a Node from the proper cache list

None

__setitem__(self, cid, content)

Updates an item from the proper cache list

30 pts for correct status of the Hash Table after mixed calls do insert, getitem and setitem (no partial credit for this set of points)

insert(self, content, evictionPolicy)

Inserts a ContentItem into the proper CacheList. After using the hash function to determine which CacheList the content should go into, call that CacheList's put method to add the content.

Input

ContentItem

content

The content item to add to the list

str

evictionPolicy

The desired eviction policy (either 'lru' or 'mru')

Output

str

(Return the output from the put method call)

__getitem__(self, content)

Returns a reference to a Node that stores a ContentItem in a CacheList. After using the hash function to determine which CacheList the content should exist in, you may use the CacheList's in operator to find the proper node. This is the special method to support the syntax object[content]

Input

ContentItem

content

The content item to retrieve

Output

Node

Reference to Node object with value that matches the ContentItem (item was found)

str

'Cache miss!' is returned if it's a cache miss (item was not found)

setitem(self, cid, content)

Updates a ContentItem. After using the hash function to determine which CacheList the content would be in, call that CacheList's update method to update the content.

Input

ContentItem

content

The content item to update

clear(self)

Clears all the lists in the hierarchy. This method is already implemented for you.

Output

str

'Cache cleared!'

class Node:

def __init__(self, content):

self.value = content

self.next = None

self.previous = None

def __str__(self):

return ('CONTENT:{} '.format(self.value))

__repr__=__str__

class ContentItem:

'''

>>> content1 = ContentItem(1000, 10, "Content-Type: 0", "0xA")

>>> content2 = ContentItem(1004, 50, "Content-Type: 1", "110010")

>>> content3 = ContentItem(1005, 18, "Content-Type: 2", "

'CMPSC132'

")

>>> content4 = ContentItem(1005, 18, "another header", "111110")

>>> hash(content1)

0

>>> hash(content2)

1

>>> hash(content3)

2

>>> hash(content4)

1

'''

def __init__(self, cid, size, header, content):

self.cid = cid

self.size = size

self.header = header

self.content = content

def __str__(self):

return f'CONTENT ID: {self.cid} SIZE: {self.size} HEADER: {self.header} CONTENT: {self.content}'

__repr__=__str__

def __eq__(self, other):

if isinstance(other, ContentItem):

return self.cid == other.cid and self.size == other.size and self.header == other.header and self.content == other.content

return False

def __hash__(self):

# YOUR CODE STARTS HERE

pass

class CacheList:

'''

>>> content1 = ContentItem(1000, 10, "Content-Type: 0", "0xA")

>>> content2 = ContentItem(1004, 50, "Content-Type: 1", "110010")

>>> content3 = ContentItem(1005, 180, "Content-Type: 2", "

'CMPSC132'

")

>>> content4 = ContentItem(1006, 18, "another header", "111110")

>>> content5 = ContentItem(1008, 2, "items", "11x1110")

>>> lst=CacheList(200)

>>> lst

REMAINING SPACE:200

ITEMS:0

LIST:

>>> lst.put(content1, 'mru')

'INSERTED: CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA'

>>> lst.put(content2, 'lru')

'INSERTED: CONTENT ID: 1004 SIZE: 50 HEADER: Content-Type: 1 CONTENT: 110010'

>>> lst.put(content4, 'mru')

'INSERTED: CONTENT ID: 1006 SIZE: 18 HEADER: another header CONTENT: 111110'

>>> lst.put(content5, 'mru')

'INSERTED: CONTENT ID: 1008 SIZE: 2 HEADER: items CONTENT: 11x1110'

>>> lst.put(content3, 'lru')

"INSERTED: CONTENT ID: 1005 SIZE: 180 HEADER: Content-Type: 2 CONTENT:

'CMPSC132'

"

>>> lst.put(content1, 'mru')

'INSERTED: CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA'

>>> 1006 in lst

True

>>> contentExtra = ContentItem(1034, 2, "items", "other content")

>>> lst.update(1008, contentExtra)

'UPDATED: CONTENT ID: 1034 SIZE: 2 HEADER: items CONTENT: other content'

>>> lst

REMAINING SPACE:170

ITEMS:3

LIST:

[CONTENT ID: 1034 SIZE: 2 HEADER: items CONTENT: other content]

[CONTENT ID: 1006 SIZE: 18 HEADER: another header CONTENT: 111110]

[CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA]

>>> lst.tail.value

CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA

>>> lst.tail.previous.value

CONTENT ID: 1006 SIZE: 18 HEADER: another header CONTENT: 111110

>>> lst.tail.previous.previous.value

CONTENT ID: 1034 SIZE: 2 HEADER: items CONTENT: other content

>>> lst.tail.previous.previous is lst.head

True

>>> lst.tail.previous.previous.previous is None

True

>>> lst.clear()

'Cleared cache!'

>>> lst

REMAINING SPACE:200

ITEMS:0

LIST:

'''

def __init__(self, size):

self.head = None

self.tail = None

self.maxSize = size

self.remainingSpace = size

self.numItems = 0

def __str__(self):

listString = ""

current = self.head

while current is not None:

listString += "[" + str(current.value) + "] "

current = current.next

return 'REMAINING SPACE:{} ITEMS:{} LIST: {}'.format(self.remainingSpace, self.numItems, listString)

__repr__=__str__

def __len__(self):

return self.numItems

def put(self, content, evictionPolicy):

# YOUR CODE STARTS HERE

if self.numItems == 0:

self.head = self.tail = Node(content)

self.remainingSpace -= content.size

self.numItems += 1

return f'INSERTED: {content}'

if content.cid in self:

return f'CONTENT ID {content.cid} ALREADY EXISTS'

if self.remainingSpace < content.size:

if evictionPolicy == 'mru':

evicted_content = self.mruEvict()

else:

evicted_content = self.lruEvict()

self.remainingSpace += evicted_content.size

new_node = Node(content)

new_node.next = self.head

self.head.previous = new_node

self.head = new_node

self.remainingSpace -= content.size

self.numItems += 1

return f'INSERTED: {content}'

new_node = Node(content)

new_node.next = self.head

self.head.previous = new_node

self.head = new_node

self.remainingSpace -= content.size

self.numItems += 1

return f'INSERTED: {content}'

def __contains__(self, cid):

# YOUR CODE STARTS HERE

current = self.head

while current is not None:

if current.value.cid == cid:

return True

current = current.next

return False

pass

def update(self, cid, content):

# YOUR CODE STARTS HERE

current = self.head

while current is not None:

if current.value.cid == cid:

self.remainingSpace += current.value.size

current.value = content

self.remainingSpace -= content.size

return f'UPDATED: {content}'

current = current.next

return f'CONTENT ID {cid} NOT FOUND'

pass

def mruEvict(self):

# YOUR CODE STARTS HERE

evicted_content = self.tail.value

if self.numItems == 1:

self.head = self.tail = None

else:

self.tail = self.tail.previous

self.tail.next = None

self.remainingSpace += evicted_content.size

self.numItems -= 1

return evicted_content

pass

def lruEvict(self):

# YOUR CODE STARTS HERE

evicted_content = self.head.value

if self.numItems == 1:

self.head = self.tail = None

else:

self.head = self.head.next

self.head.previous = None

self.remainingSpace += evicted_content.size

self.numItems -= 1

return evicted_content

pass

def clear(self):

# YOUR CODE STARTS HERE

self.head = self.tail = None

self.remainingSpace = self.maxSize

self.numItems = 0

return 'Cleared cache!'

pass

class Cache:

"""

>>> cache = Cache(205)

>>> content1 = ContentItem(1000, 10, "Content-Type: 0", "0xA")

>>> content2 = ContentItem(1003, 13, "Content-Type: 0", "0xD")

>>> content3 = ContentItem(1008, 242, "Content-Type: 0", "0xF2")

>>> content4 = ContentItem(1004, 50, "Content-Type: 1", "110010")

>>> content5 = ContentItem(1001, 51, "Content-Type: 1", "110011")

>>> content6 = ContentItem(1007, 155, "Content-Type: 1", "10011011")

>>> content7 = ContentItem(1005, 23, "Content-Type: 2", "

'CMPSC132'

")

>>> content8 = ContentItem(1002, 14, "Content-Type: 2", "

'PSU'

")

>>> content9 = ContentItem(1006, 170, "Content-Type: 2", "")

>>> cache.insert(content1, 'lru')

'INSERTED: CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA'

>>> cache.insert(content2, 'lru')

'INSERTED: CONTENT ID: 1003 SIZE: 13 HEADER: Content-Type: 0 CONTENT: 0xD'

>>> cache.insert(content3, 'lru')

'Insertion not allowed'

>>> cache.insert(content4, 'lru')

'INSERTED: CONTENT ID: 1004 SIZE: 50 HEADER: Content-Type: 1 CONTENT: 110010'

>>> cache.insert(content5, 'lru')

'INSERTED: CONTENT ID: 1001 SIZE: 51 HEADER: Content-Type: 1 CONTENT: 110011'

>>> cache.insert(content6, 'lru')

'INSERTED: CONTENT ID: 1007 SIZE: 155 HEADER: Content-Type: 1 CONTENT: 10011011'

>>> cache.insert(content7, 'lru')

"INSERTED: CONTENT ID: 1005 SIZE: 23 HEADER: Content-Type: 2 CONTENT:

'CMPSC132'

"

>>> cache.insert(content8, 'lru')

"INSERTED: CONTENT ID: 1002 SIZE: 14 HEADER: Content-Type: 2 CONTENT:

'PSU'

"

>>> cache.insert(content9, 'lru')

"INSERTED: CONTENT ID: 1006 SIZE: 170 HEADER: Content-Type: 2 CONTENT: "

>>> cache

L1 CACHE:

REMAINING SPACE:182

ITEMS:2

LIST:

[CONTENT ID: 1003 SIZE: 13 HEADER: Content-Type: 0 CONTENT: 0xD]

[CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA]

L2 CACHE:

REMAINING SPACE:50

ITEMS:1

LIST:

[CONTENT ID: 1007 SIZE: 155 HEADER: Content-Type: 1 CONTENT: 10011011]

L3 CACHE:

REMAINING SPACE:21

ITEMS:2

LIST:

[CONTENT ID: 1006 SIZE: 170 HEADER: Content-Type: 2 CONTENT: ]

[CONTENT ID: 1002 SIZE: 14 HEADER: Content-Type: 2 CONTENT:

'PSU'

]

>>> cache.hierarchy[0].clear()

'Cleared cache!'

>>> cache.hierarchy[1].clear()

'Cleared cache!'

>>> cache.hierarchy[2].clear()

'Cleared cache!'

>>> cache

L1 CACHE:

REMAINING SPACE:205

ITEMS:0

LIST:

L2 CACHE:

REMAINING SPACE:205

ITEMS:0

LIST:

L3 CACHE:

REMAINING SPACE:205

ITEMS:0

LIST:

>>> cache.insert(content1, 'mru')

'INSERTED: CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA'

>>> cache.insert(content2, 'mru')

'INSERTED: CONTENT ID: 1003 SIZE: 13 HEADER: Content-Type: 0 CONTENT: 0xD'

>>> cache[content1].value

CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA

>>> cache[content2].value

CONTENT ID: 1003 SIZE: 13 HEADER: Content-Type: 0 CONTENT: 0xD

>>> cache[content3]

'Cache miss!'

>>> cache.insert(content5, 'lru')

'INSERTED: CONTENT ID: 1001 SIZE: 51 HEADER: Content-Type: 1 CONTENT: 110011'

>>> content6 = ContentItem(1007, 160, "Content-Type: 1", "10011011")

>>> cache.insert(content6, 'lru')

'INSERTED: CONTENT ID: 1007 SIZE: 160 HEADER: Content-Type: 1 CONTENT: 10011011'

>>> cache.insert(content4, 'lru')

'INSERTED: CONTENT ID: 1004 SIZE: 50 HEADER: Content-Type: 1 CONTENT: 110010'

>>> cache.insert(content7, 'mru')

"INSERTED: CONTENT ID: 1005 SIZE: 23 HEADER: Content-Type: 2 CONTENT:

'CMPSC132'

"

>>> cache.insert(content8, 'mru')

"INSERTED: CONTENT ID: 1002 SIZE: 14 HEADER: Content-Type: 2 CONTENT:

'PSU'

"

>>> cache.insert(content9, 'mru')

"INSERTED: CONTENT ID: 1006 SIZE: 170 HEADER: Content-Type: 2 CONTENT: "

>>> cache

L1 CACHE:

REMAINING SPACE:182

ITEMS:2

LIST:

[CONTENT ID: 1003 SIZE: 13 HEADER: Content-Type: 0 CONTENT: 0xD]

[CONTENT ID: 1000 SIZE: 10 HEADER: Content-Type: 0 CONTENT: 0xA]

L2 CACHE:

REMAINING SPACE:155

ITEMS:1

LIST:

[CONTENT ID: 1004 SIZE: 50 HEADER: Content-Type: 1 CONTENT: 110010]

L3 CACHE:

REMAINING SPACE:12

ITEMS:2

LIST:

[CONTENT ID: 1006 SIZE: 170 HEADER: Content-Type: 2 CONTENT: ]

[CONTENT ID: 1005 SIZE: 23 HEADER: Content-Type: 2 CONTENT:

'CMPSC132'

]

>>> cache.clear()

'Cache cleared!'

>>> contentA = ContentItem(2000, 52, "Content-Type: 2", "GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1")

>>> contentB = ContentItem(2001, 76, "Content-Type: 2", "GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1")

>>> contentC = ContentItem(2002, 11, "Content-Type: 2", "GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1")

>>> cache.insert(contentA, 'lru')

'INSERTED: CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1'

>>> cache.insert(contentB, 'lru')

'INSERTED: CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1'

>>> cache.insert(contentC, 'lru')

'INSERTED: CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1'

>>> cache.hierarchy[2]

REMAINING SPACE:66

ITEMS:3

LIST:

[CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1]

[CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1]

[CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1]

>>> cache[contentC].value

CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1

>>> cache.hierarchy[2]

REMAINING SPACE:66

ITEMS:3

LIST:

[CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1]

[CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1]

[CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1]

>>> cache[contentA].next.previous.value

CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1

>>> cache.hierarchy[2]

REMAINING SPACE:66

ITEMS:3

LIST:

[CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1]

[CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1]

[CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1]

>>> cache[contentC].next.previous.value

CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1

>>> cache.hierarchy[2]

REMAINING SPACE:66

ITEMS:3

LIST:

[CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1]

[CONTENT ID: 2000 SIZE: 52 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201802040nwe.htm HTTP/1.1]

[CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1]

>>> contentD = ContentItem(2002, 11, "Content-Type: 2", "GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1")

>>> cache.insert(contentD, 'lru')

'Content 2002 already in cache, insertion not allowed'

>>> contentE = ContentItem(2000, 103, "Content-Type: 2", "GET https://www.pro-football-reference.com/boxscores/201801210phi.htm HTTP/1.1")

>>> cache[2000] = contentE

>>> cache.hierarchy[2]

REMAINING SPACE:15

ITEMS:3

LIST:

[CONTENT ID: 2000 SIZE: 103 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201801210phi.htm HTTP/1.1]

[CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1]

[CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1]

>>> cache.hierarchy[2].tail.value

CONTENT ID: 2001 SIZE: 76 HEADER: Content-Type: 2 CONTENT: GET https://giphy.com/gifs/93lCI4D0murAszeyA6/html5 HTTP/1.1

>>> cache.hierarchy[2].tail.previous.value

CONTENT ID: 2002 SIZE: 11 HEADER: Content-Type: 2 CONTENT: GET https://media.giphy.com/media/YN7akkfUNQvT1zEBhO/giphy-downsized.gif HTTP/1.1

>>> cache.hierarchy[2].tail.previous.previous.value

CONTENT ID: 2000 SIZE: 103 HEADER: Content-Type: 2 CONTENT: GET https://www.pro-football-reference.com/boxscores/201801210phi.htm HTTP/1.1

>>> cache.hierarchy[2].tail.previous.previous is cache.hierarchy[2].head

True

>>> cache.hierarchy[2].tail.previous.previous.previous is None

True

"""

def __init__(self, lst_capacity):

self.hierarchy = [CacheList(lst_capacity), CacheList(lst_capacity), CacheList(lst_capacity)]

self.size = 3

def __str__(self):

return ('L1 CACHE: {} L2 CACHE: {} L3 CACHE: {} '.format(self.hierarchy[0], self.hierarchy[1], self.hierarchy[2]))

__repr__=__str__

def clear(self):

for item in self.hierarchy:

item.clear()

return 'Cache cleared!'

def insert(self, content, evictionPolicy):

# YOUR CODE STARTS HERE

res = self.hierarchy[self.hashFunc(content.header)].put(content, evictionPolicy)

return res or f'INSERTED: {content}'

pass

def __getitem__(self, content):

# YOUR CODE STARTS HERE

pass

def __setitem__(self, cid, content):

# YOUR CODE STARTS HERE

pass

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!