With queue, add() is not O(1), get() is difficult/hacky to implement. So deque.
// caches n recently used items
lru-cache:
n // items
ctor(n):
n = n
count = 0
map
q
add(key, value):
if map.has(key):
// update value, move node to end of dq
item = map[key]
item.value = value
// difficult: item.node need to be put at end
return
if count == n:
// remove lru item
// handle delayed removal from queue
lrukey = q.dequeue()
while !map.has(lrukey):
lrukey = q.dequeue()
map.remove(lrukey)
count--
// add key
count++
q.enqueue(key)
map.add(key, value)
remove(key):
if !map.has(key):
return // or throw "error"
count--
// only remove from map, delay removal from queue during add
map.remove(key)
has(key):
return map.has(key)
get(key):
// difficult/hacky to implement
dq = new deque{key}()
nodemap = new map{key, node{key}}()
valuemap = new map{key, value}()
add(key, value):
if key == null || value == null: throw
if has(key):
// nodemap does not change
dq.makeTail(nodemap[key])
valuemap[key] = value
return
if count == n:
// remove lru
lrukey = dq.peek()
removeInternal(lrukey)
// add to end
addInternal(key, value)
value removeInternal(key):
dq.removeNode(nodemap[key])
nodemap.remove(key)
value = valuemap[key]
valuemap.remove(key)
count--
return value
addInternal(key, value):
node = dq.enqueue(key)
nodemap[key] = node
valuemap[key] = value
count++
bool remove(key):
if key == null: throw
// do not throw if key no exists
if !has(key):
return false
removeInternal(key)
return true
value get(key):
if key == null: throw
// do not throw if key no exists
if !has(key):
return null // default(value)
dq.makeTail(nodemap[key])
return valuemap[key]
bool haskey(key):
if key == null: throw
return valuemap.haskey(key)
int count():
return count
// deque interface
deque{key}:
// for removal in O(1) time
node{key} enqueue(key):
removeNode(node{key})
// moves dq node to end
makeTail(node):
key peek():
// not used
key dequeue():
No comments:
Post a Comment