Yet another cache

Faster in microbenchmarks on the cache::

```
import com.twitter.summingbird.online.option._
import com.twitter.summingbird.option.CacheSize
import com.twitter.algebird._
import com.twitter.summingbird.online._
import com.twitter.util.Duration
import scala.util.Random
import com.twitter.bijection._

val cacheSize = CacheSize(1000)
val flushFrequency = FlushFrequency(Duration.fromMilliseconds(100))
val memFlushPer = SoftMemoryFlushPercent(80.0f)
val combiner = ValueCombinerCacheSize(10)
val poolSize = AsyncPoolSize(1)
val numInputItems = 100000L


implicit val hllMonoid = new HyperLogLogMonoid(24)

def hll[T](t: T)(implicit monoid: HyperLogLogMonoid, inj: Injection[T, Array[Byte]]): HLL = monoid.create(inj(t))

val inputItems: List[(Long, HLL)] = Random.shuffle(((0L until numInputItems).map {inputKey =>
  if(inputKey % 100 == 0) { // 1% be hot keys
    (0L until 100L).map {valIndex => // hot keys have 10x more data
      (inputKey, hll(Random.nextLong))
    }
    } else {
    (0L until 10L).map {valIndex =>
      (inputKey, hll(Random.nextLong))
    }
  }
}).flatten).toList

def buildCaches[Key, Value](implicit sg: Semigroup[Value]) = 
  List(
    YetAnotherCache[Key, Value](cacheSize, flushFrequency, memFlushPer),
    SummingQueueCache[Key, Value](cacheSize, flushFrequency),
    MultiTriggerCache[Key, Value](CacheSize(cacheSize.lowerBound/10), combiner, flushFrequency, memFlushPer, poolSize)
  )

val caches = buildCaches[Long, HLL]

val th = new com.ichi.bench.Thyme

import com.twitter.util.{Await, Future}
def fn(cache: AsyncCache[Long, HLL]): Int = {
  val results = (inputItems.map(item => cache.insert(List(item)).unit) :+ cache.forceTick.unit)
  Await.result(Future.collect(results.toIndexedSeq)).size
}

println("Yet another vs Summing queue")
th.benchOffPair()(fn(caches(0)))(fn(caches(1)))


println("Yet another vs MultiTrigger")
th.benchOffPair()(fn(caches(0)))(fn(caches(2)))
```