Add an AddIfNotPresent function to support single producer/consumer
retry scenarios. Provides the consumer with a means to prefer items
already enqueued by the producer at the point of retry.
Without the ability to retrieve underlying items by key (instead of
the object passed to KeyFunc) it is impossible to build wrappers
around cache.Store that want to make decisions about keys, because
they would need to reconstruct the object passed to Get.
This allows retrieval by key, and makes sure Get(obj) uses it.
Support namespacing in cache.Store by framing the interface functions
around interface{} and providing a key function to each Store implementation.
Implementation of a fix for #2294.
Keep the FIFO's internal set in sync with the queue during Add/Update
operations to prevent a queue line-jumping scenario (described in a
new unit test).