public virtual double Remove(E key)
        {
            AtomicDouble atomic = map[key];

            if (atomic == null)
            {
                return(defaultReturnValue);
            }
            for (; ;)
            {
                double oldValue = atomic.Get();
                if (oldValue == 0.0 || atomic.CompareAndSet(oldValue, 0.0))
                {
                    // only remove after setting to zero, to avoid concurrent updates
                    Sharpen.Collections.Remove(map, key, atomic);
                    // succeed even if the remove fails, since the value was already adjusted
                    totalCount.AddAndGet(-1.0 * oldValue);
                    return(oldValue);
                }
            }
        }
 public virtual double LogIncrementCount(E key, double value)
 {
     // TODO Inspired by Guava.AtomicLongMap
     // Modify for our use?
     for (; ;)
     {
         AtomicDouble atomic = map[key];
         if (atomic == null)
         {
             atomic = map.PutIfAbsent(key, new AtomicDouble(value));
             if (atomic == null)
             {
                 totalCount.AddAndGet(value);
                 return(value);
             }
         }
         for (; ;)
         {
             double oldValue = atomic.Get();
             if (oldValue == 0.0)
             {
                 // don't compareAndSet a zero
                 if (map.Replace(key, atomic, new AtomicDouble(value)))
                 {
                     totalCount.AddAndGet(value);
                     return(value);
                 }
                 goto outer_continue;
             }
             double newValue = SloppyMath.LogAdd(oldValue, value);
             if (atomic.CompareAndSet(oldValue, newValue))
             {
                 totalCount.AddAndGet(value);
                 return(newValue);
             }
         }
         outer_continue :;
     }
     outer_break :;
 }
        public virtual double GetCount(object key)
        {
            AtomicDouble v = map[key];

            return(v == null ? defaultReturnValue : v.Get());
        }
 public ConcurrentHashCounter(int initialCapacity)
 {
     map        = new ConcurrentHashMap <E, AtomicDouble>(initialCapacity);
     totalCount = new AtomicDouble();
 }