Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increment operator #10

Open
jadbox opened this issue Jun 27, 2016 · 7 comments · May be fixed by #72
Open

Increment operator #10

jadbox opened this issue Jun 27, 2016 · 7 comments · May be fixed by #72

Comments

@jadbox
Copy link

jadbox commented Jun 27, 2016

It would be great that instead of a Get+Set that there was an Increment operator, ideally goroutine safe.

@bluele
Copy link
Owner

bluele commented Jul 14, 2016

Sorry for late reply.
Thanks your advice. I'm planning to implement GetAndSet method which enables a such operation.

@erwanor
Copy link
Contributor

erwanor commented May 25, 2017

@bluele If you detail the spec you have in mind for that method, I'll be happy to implement it.

@bluele
Copy link
Owner

bluele commented May 25, 2017

Thanks, @aaronwinter .
Hmm... How about with the following design?

func (c *LRUCache) GetOrSet(key, value interface{}) (interface{}, error) {
	v, err := c.get(key, false)
	if err == KeyNotFoundError {
        it, err := c.set(key, value)
        return it.value, err
	}
	return v, err
}

Or is it better to give a function that returns a value rather than a value?

@pcman312
Copy link
Contributor

pcman312 commented Jun 8, 2017

This seems potentially problematic to design because of the problem of dealing with interface{} and then having to interpret those values as one of the numeric values. You could potentially have two Increment methods, one for integers and one for floats that attempts to enforce int64 and float64 respectively.

@sergerdn
Copy link

sergerdn commented Jan 22, 2021

https://github.com/patrickmn/go-cache/blob/master/cache.go#L182

// 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. To retrieve the incremented value, use one
// of the specialized methods, e.g. IncrementInt64.
func (c *cache) Increment(k string, n int64) error {
	c.mu.Lock()
	v, found := c.items[k]
	if !found || v.Expired() {
		c.mu.Unlock()
		return fmt.Errorf("Item %s not found", k)
	}
	switch v.Object.(type) {
	case int:
		v.Object = v.Object.(int) + int(n)
	case int8:
		v.Object = v.Object.(int8) + int8(n)
	case int16:
		v.Object = v.Object.(int16) + int16(n)
	case int32:
		v.Object = v.Object.(int32) + int32(n)
	case int64:
		v.Object = v.Object.(int64) + n
	case uint:
		v.Object = v.Object.(uint) + uint(n)
	case uintptr:
		v.Object = v.Object.(uintptr) + uintptr(n)
	case uint8:
		v.Object = v.Object.(uint8) + uint8(n)
	case uint16:
		v.Object = v.Object.(uint16) + uint16(n)
	case uint32:
		v.Object = v.Object.(uint32) + uint32(n)
	case uint64:
		v.Object = v.Object.(uint64) + uint64(n)
	case float32:
		v.Object = v.Object.(float32) + float32(n)
	case float64:
		v.Object = v.Object.(float64) + float64(n)
	default:
		c.mu.Unlock()
		return fmt.Errorf("The value for %s is not an integer", k)
	}
	c.items[k] = v
	c.mu.Unlock()
	return nil
}

@sergerdn sergerdn linked a pull request Jan 23, 2021 that will close this issue
@jadbox
Copy link
Author

jadbox commented Feb 1, 2021

@sergerdn I think that's the best solution here that you posted above (at least until Go gets generic typing support).

@sergerdn
Copy link

sergerdn commented Feb 1, 2021

@sergerdn I think that's the best solution here that you posted above (at least until Go gets generic typing support).

@jadbox Have a look another solution with code generators, it looks not bad too:

It supports decrement also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants