// incrementOffset is a common incrementor method used between Increment and // Decrement. If the key isn't set before, we will set the initial value. If // there is a value present, we will add the given offset to that value and // update the value with the new TTL. func (c *Cache) incrementOffset(key string, initial, offset, ttl int64) error { c.client.Do("WATCH", key) if err := c.exists(key); err != nil { c.client.Do("MULTI") defer c.client.Do("EXEC") return c.Set(key, encoding.Int64Bytes(initial), ttl) } getValue, _, err := c.Get(key) if err != nil { return err } val, ok := encoding.BytesInt64(getValue) if !ok { return errors.NewEncoding(key) } // We are watching our key. With using a transaction, we can check that this // increment doesn't inflect with another concurrent request that might // happen. c.client.Do("MULTI") defer c.client.Do("EXEC") val += offset if val < 0 { return errors.NewValueBelowZero(key) } return c.Set(key, encoding.Int64Bytes(val), ttl) }
// incrementOffset is a common incrementor method used between Increment and // Decrement. If the key isn't set before, we will set the initial value. If // there is a value present, we will add the given offset to that value and // update the value with the new TTL. func (c *Cache) incrementOffset(key string, initial, offset, ttl int64) error { if err := c.exists(key); err != nil { return c.Set(key, encoding.Int64Bytes(initial), ttl) } val, ok := encoding.BytesInt64(c.items[key].value) if !ok { return errors.NewEncoding(key) } val += offset if val < 0 { return errors.NewValueBelowZero(key) } return c.Set(key, encoding.Int64Bytes(val), ttl) }