2
0

Add specialized increment and decrement methods

This commit is contained in:
Patrick Mylund Nielsen
2013-04-18 14:24:30 -04:00
parent b5601e904d
commit d5d03c28d4
3 changed files with 1584 additions and 125 deletions
+631 -30
View File
@@ -18,8 +18,35 @@ type unexportedInterface interface {
Replace(string, interface{}, time.Duration) error
Get(string) (interface{}, bool)
Increment(string, int64) error
IncrementInt(string, int) (int, error)
IncrementInt8(string, int8) (int8, error)
IncrementInt16(string, int16) (int16, error)
IncrementInt32(string, int32) (int32, error)
IncrementInt64(string, int64) (int64, error)
IncrementUint(string, uint) (uint, error)
IncrementUintptr(string, uintptr) (uintptr, error)
IncrementUint8(string, uint8) (uint8, error)
IncrementUint16(string, uint16) (uint16, error)
IncrementUint32(string, uint32) (uint32, error)
IncrementUint64(string, uint64) (uint64, error)
IncrementFloat(string, float64) error
IncrementFloat32(string, float32) (float32, error)
IncrementFloat64(string, float64) (float64, error)
Decrement(string, int64) error
DecrementInt(string, int) (int, error)
DecrementInt8(string, int8) (int8, error)
DecrementInt16(string, int16) (int16, error)
DecrementInt32(string, int32) (int32, error)
DecrementInt64(string, int64) (int64, error)
DecrementUint(string, uint) (uint, error)
DecrementUintptr(string, uintptr) (uintptr, error)
DecrementUint8(string, uint8) (uint8, error)
DecrementUint16(string, uint16) (uint16, error)
DecrementUint32(string, uint32) (uint32, error)
DecrementUint64(string, uint64) (uint64, error)
DecrementFloat(string, float64) error
DecrementFloat32(string, float32) (float32, error)
DecrementFloat64(string, float64) (float64, error)
Delete(string)
DeleteExpired()
Flush()
@@ -87,7 +114,7 @@ func (c *cache) Add(k string, x interface{}, d time.Duration) error {
_, found := c.get(k)
if found {
c.Unlock()
return fmt.Errorf("item %s already exists", k)
return fmt.Errorf("Item %s already exists", k)
}
c.set(k, x, d)
c.Unlock()
@@ -101,7 +128,7 @@ func (c *cache) Replace(k string, x interface{}, d time.Duration) error {
_, found := c.get(k)
if !found {
c.Unlock()
return fmt.Errorf("item %s doesn't exist", k)
return fmt.Errorf("Item %s doesn't exist", k)
}
c.set(k, x, d)
c.Unlock()
@@ -129,40 +156,17 @@ func (c *cache) get(k string) (interface{}, bool) {
return item.Object, true
}
// Increment an item of type float32 or float64 by n. Returns an error if the
// item's value is not floating point, if it was not found, or if it is not
// possible to increment it by n. Pass a negative number to decrement the
// value.
func (c *cache) IncrementFloat(k string, n float64) error {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return fmt.Errorf("item not found")
}
switch v.Object.(type) {
case float32:
v.Object = v.Object.(float32) + float32(n)
case float64:
v.Object = v.Object.(float64) + n
default:
c.Unlock()
return fmt.Errorf("The value for %s does not have type float32 or float64", k)
}
c.Unlock()
return nil
}
// Increment an item of type int, int8, int16, int32, int64, uintptr, uint,
// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the
// item's value is not an integer, if it was not found, or if it is not
// possible to increment it by n.
// possible to increment it by n. To retrieve the incremented value, use one
// of the specialized methods, e.g. IncrementInt64.
func (c *cache) Increment(k string, n int64) error {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return fmt.Errorf("item not found")
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case int:
@@ -199,10 +203,309 @@ func (c *cache) Increment(k string, n int64) error {
return nil
}
// Increment an item of type float32 or float64 by n. Returns an error if the
// item's value is not floating point, if it was not found, or if it is not
// possible to increment it by n. Pass a negative number to decrement the
// value. To retrieve the incremented value, use one of the specialized methods,
// e.g. IncrementFloat64.
func (c *cache) IncrementFloat(k string, n float64) error {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case float32:
v.Object = v.Object.(float32) + float32(n)
case float64:
v.Object = v.Object.(float64) + n
default:
c.Unlock()
return fmt.Errorf("The value for %s does not have type float32 or float64", k)
}
c.Unlock()
return nil
}
// Increment an item of type int by n. Returns an error if the item's value is
// not an int, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementInt(k string, n int) (int, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type int8 by n. Returns an error if the item's value is
// not an int8, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementInt8(k string, n int8) (int8, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int8)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int8", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type int16 by n. Returns an error if the item's value is
// not an int16, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementInt16(k string, n int16) (int16, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int16)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int16", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type int32 by n. Returns an error if the item's value is
// not an int32, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementInt32(k string, n int32) (int32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int32", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type int64 by n. Returns an error if the item's value is
// not an int64, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementInt64(k string, n int64) (int64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int64", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uint by n. Returns an error if the item's value is
// not an uint, or if it was not found. If there is no error, the incremented
// value is returned.
func (c *cache) IncrementUint(k string, n uint) (uint, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uintptr by n. Returns an error if the item's value
// is not an uintptr, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementUintptr(k string, n uintptr) (uintptr, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uintptr)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uintptr", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uint8 by n. Returns an error if the item's value
// is not an uint8, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementUint8(k string, n uint8) (uint8, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint8)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint8", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uint16 by n. Returns an error if the item's value
// is not an uint16, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementUint16(k string, n uint16) (uint16, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint16)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint16", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uint32 by n. Returns an error if the item's value
// is not an uint32, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementUint32(k string, n uint32) (uint32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint32", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type uint64 by n. Returns an error if the item's value
// is not an uint64, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementUint64(k string, n uint64) (uint64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint64", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type float32 by n. Returns an error if the item's value
// is not an float32, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementFloat32(k string, n float32) (float32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an float32", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Increment an item of type float64 by n. Returns an error if the item's value
// is not an float64, or if it was not found. If there is no error, the
// incremented value is returned.
func (c *cache) IncrementFloat64(k string, n float64) (float64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an float64", k)
}
nv := rv + n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type int, int8, int16, int32, int64, uintptr, uint,
// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the
// item's value is not an integer, if it was not found, or if it is not
// possible to decrement it by n.
// possible to decrement it by n. To retrieve the decremented value, use one
// of the specialized methods, e.g. DecrementInt64.
func (c *cache) Decrement(k string, n int64) error {
// TODO: Implement Increment and Decrement more cleanly.
// (Cannot do Increment(k, n*-1) for uints.)
@@ -210,7 +513,7 @@ func (c *cache) Decrement(k string, n int64) error {
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return fmt.Errorf("item not found")
return fmt.Errorf("Item not found")
}
switch v.Object.(type) {
case int:
@@ -247,6 +550,304 @@ func (c *cache) Decrement(k string, n int64) error {
return nil
}
// Decrement an item of type float32 or float64 by n. Returns an error if the
// item's value is not floating point, if it was not found, or if it is not
// possible to decrement it by n. Pass a negative number to decrement the
// value. To retrieve the decremented value, use one of the specialized methods,
// e.g. DecrementFloat64.
func (c *cache) DecrementFloat(k string, n float64) error {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case float32:
v.Object = v.Object.(float32) - float32(n)
case float64:
v.Object = v.Object.(float64) - n
default:
c.Unlock()
return fmt.Errorf("The value for %s does not have type float32 or float64", k)
}
c.Unlock()
return nil
}
// Decrement an item of type int by n. Returns an error if the item's value is
// not an int, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementInt(k string, n int) (int, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type int8 by n. Returns an error if the item's value is
// not an int8, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementInt8(k string, n int8) (int8, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int8)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int8", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type int16 by n. Returns an error if the item's value is
// not an int16, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementInt16(k string, n int16) (int16, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int16)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int16", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type int32 by n. Returns an error if the item's value is
// not an int32, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementInt32(k string, n int32) (int32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int32", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type int64 by n. Returns an error if the item's value is
// not an int64, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementInt64(k string, n int64) (int64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an int64", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uint by n. Returns an error if the item's value is
// not an uint, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementUint(k string, n uint) (uint, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uintptr by n. Returns an error if the item's value
// is not an uintptr, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementUintptr(k string, n uintptr) (uintptr, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uintptr)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uintptr", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uint8 by n. Returns an error if the item's value is
// not an uint8, or if it was not found. If there is no error, the decremented
// value is returned.
func (c *cache) DecrementUint8(k string, n uint8) (uint8, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint8)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint8", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uint16 by n. Returns an error if the item's value
// is not an uint16, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementUint16(k string, n uint16) (uint16, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint16)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint16", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uint32 by n. Returns an error if the item's value
// is not an uint32, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementUint32(k string, n uint32) (uint32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint32", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type uint64 by n. Returns an error if the item's value
// is not an uint64, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementUint64(k string, n uint64) (uint64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint64", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type float32 by n. Returns an error if the item's value
// is not an float32, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementFloat32(k string, n float32) (float32, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float32)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an float32", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Decrement an item of type float64 by n. Returns an error if the item's value
// is not an float64, or if it was not found. If there is no error, the
// decremented value is returned.
func (c *cache) DecrementFloat64(k string, n float64) (float64, error) {
c.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float64)
if !ok {
c.Unlock()
return 0, fmt.Errorf("The value for %s is not an float64", k)
}
nv := rv - n
v.Object = nv
c.Unlock()
return nv, nil
}
// Delete an item from the cache. Does nothing if the key is not in the cache.
func (c *cache) Delete(k string) {
c.Lock()