// goMerge takes existing and update byte slices. It first attempts // to gob-unmarshal the update string, returning an error on failure. // The unmarshaled value must satisfy the Mergable interface. // Next, it unmarshals the existing string, falling back to the init // value supplied by the update value's Init() method if necessary. // The two values obtained in this way are merged and the result, or // an error, returned. func goMerge(existing, update []byte) ([]byte, error) { u, err := encoding.GobDecode(update) if err != nil { return nil, util.Errorf("merge: %v", err) } if _, ok := u.(Mergable); !ok { return nil, util.Error("update is not Mergable") } e, err := encoding.GobDecode(existing) if err != nil { e = u.(Mergable).Init(existing) } if reflect.TypeOf(u) != reflect.TypeOf(e) { return nil, util.Error("cannot merge values of different type") } newValue, err := e.(Mergable).Merge(u.(Mergable)) if err != nil { return nil, err } return encoding.GobEncode(newValue) }
// Slice returns the data stored in the underlying storage. func (es *EngineSampleStorage) Slice() []interface{} { startKey := MakeKey(es.prefix, keyDataPrefix) res, err := es.engine.scan( startKey, PrefixEndKey(startKey), es.Seen()) if err != nil { glog.Warning(err) return nil } sl := make([]interface{}, len(res)) for i, kv := range res { if dv, err := encoding.GobDecode(kv.value); err == nil { sl[i] = dv } else { glog.Warning(err) } } return sl }