Implements an LFU eviction strategy nspired by the O(1) algorithm for LFU cache inviction
http://dhruvbird.com/lfu.pdf.
We maintain a linked list, where each node represents all the keys for blocks that are equally popular (popularity being measured as the number of reads).
When the node reaches a maximum disk capacity in bytes it pops out keys to delete until it is below that capacity. The removed keys are the eldest in the store + the least popular (i.e the lowest level node in the frequency linked list). The evicted keys are then used to evict content from the blockstore.
For O(1) in evicting content from this list we maintain a lookup table which maps CIDS/Hashes to pointer elements in the linked list.
Tests for all operations
LFU implements the BlockStore trait so is directly swappable into the PoP node as is.
LFU automatically syncs keys from a blockstore loaded from disk -- so it can recover from reboots.