Beispiel #1
0
// GetMulti returns several objects with only one trip to the cache.
// The queried keys are the ones set in the out parameter. Any key present
// in out and not found when querying the cache, will be deleted. The initial
// values in the out map should be any value of the type which will be used
// to decode the data for the given key.
// e.g. Let's suppose our cache holds 3 objects: k1 of type []int, k2 of type
// float64 and k3 of type string. To query for these 3 objects using GetMulti
// you would initialze out like this:
//
//  out := map[string]interface{}{
//	k1: []int(nil),
//	k2: float(0),
//	k3: "",
//  }
//  err := c.GetMulti(out, nil)
//
// After the GetMulti() call, any keys not present in the cache will be
// deleted from out, so len(out) will be <= 3 in this example.
//
// Alternatively, the second argument might be used to specify the types
// of the object to be decoded. Users might implement their own Typer
// or use UniTyper when requesting several objects of the same type.
func (c *Cache) GetMulti(out map[string]interface{}, typer Typer) error {
	keys := make([]string, 0, len(out))
	for k := range out {
		keys = append(keys, k)
	}
	if profile.On && profile.Profiling() {
		defer profile.Startf(cache, "GET MULTI", "%v", keys).End()
	}
	qkeys := keys
	if c.prefixLen > 0 {
		qkeys = make([]string, len(keys))
		for ii, v := range keys {
			qkeys[ii] = c.backendKey(v)
		}
	}
	data, err := c.driver.GetMulti(qkeys)
	if err != nil {
		gerr := &cacheError{
			op:  "getting multiple keys",
			key: strings.Join(keys, ", "),
			err: err,
		}
		c.error(gerr)
		return gerr
	}
	if typer == nil {
		typer = mapTyper(out)
	}
	for ii, k := range keys {
		value := data[qkeys[ii]]
		if value == nil {
			delete(out, k)
			continue
		}
		typ := typer.Type(k)
		if typ == nil {
			derr := &cacheError{
				op:  "determining output type for object",
				key: k,
				err: fmt.Errorf("untyped value for key %q - please, set the value type like e.g. out[%q] = ([]int)(nil) or out[%q] = float64(0)", k, k, k),
			}
			c.error(derr)
			return derr
		}
		val := reflect.New(typ)
		err := c.codec.Decode(value, val.Interface())
		if err != nil {
			derr := &cacheError{
				op:  "decoding object",
				key: k,
				err: err,
			}
			c.error(derr)
			return derr
		}
		out[k] = val.Elem().Interface()
	}
	return nil
}
Beispiel #2
0
// Delete removes the key from the cache. An error is returned only
// if the item was found but couldn't be deleted. Deleting a non-existant
// item is always successful.
func (c *Cache) Delete(key string) error {
	if profile.On {
		defer profile.Startf(cache, "DELETE %s", key).End()
	}
	err := c.driver.Delete(c.backendKey(key))
	if err != nil {
		derr := &cacheError{
			op:  "deleting",
			key: key,
			err: err,
		}
		c.error(derr)
		return derr
	}
	return nil
}