From 00d9423598d7718db56fb152972ba23e793788f3 Mon Sep 17 00:00:00 2001 From: Benjamin Wenger <ben@elixxir.ioo> Date: Fri, 5 Mar 2021 14:14:39 -0800 Subject: [PATCH] implemented the upgrade fix, needs fixes --- storage/versioned/kv.go | 79 +++++++++++++++++++++-------------------- ud/registered.go | 2 +- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/storage/versioned/kv.go b/storage/versioned/kv.go index 72e0386de..58e81770f 100644 --- a/storage/versioned/kv.go +++ b/storage/versioned/kv.go @@ -12,7 +12,6 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/ekv" "gitlab.com/xx_network/primitives/id" - "strings" ) const PrefixSeparator = "/" @@ -30,11 +29,11 @@ func MakePartnerPrefix(id *id.ID) string { } // Upgrade functions must be of this type -type Upgrade func(key string, oldObject *Object) (*Object, +type Upgrade func(oldObject *Object) (*Object, error) + type root struct { - upgradeTable map[string]Upgrade data ekv.KeyValue } @@ -48,29 +47,7 @@ type KV struct { func NewKV(data ekv.KeyValue) *KV { newKV := KV{} root := root{} - // Add new Upgrade functions to this Upgrade table - root.upgradeTable = make(map[string]Upgrade) - // All Upgrade functions should Upgrade to the latest version. You can - // call older Upgrade functions if you need to. Upgrade functions don't - // change the key or store the upgraded version of the data in the - // key/value store. There's no mechanism built in for this -- users - // should always make the key prefix before calling Set, and if they - // want the upgraded data persisted they should call Set with the - // upgraded data. - root.upgradeTable[MakeKeyWithPrefix("test", "")] = func(key string, - oldObject *Object) (*Object, error) { - if oldObject.Version == 1 { - return oldObject, nil - } - return &Object{ - Version: 1, - // Upgrade functions don't need to update - // the timestamp - Timestamp: oldObject.Timestamp, - Data: []byte("this object was upgraded from" + - " v0 to v1"), - }, nil - } + root.data = data newKV.r = &root @@ -81,7 +58,7 @@ func NewKV(data ekv.KeyValue) *KV { // Get gets and upgrades data stored in the key/value store // Make sure to inspect the version returned in the versioned object func (v *KV) Get(key string) (*Object, error) { - key = v.prefix + key + key = v.makeKey(key) jww.TRACE.Printf("Get %p with key %v", v.r.data, key) // Get raw data result := Object{} @@ -89,23 +66,43 @@ func (v *KV) Get(key string) (*Object, error) { if err != nil { return nil, err } - // If the key starts with a version tag that we can find in the table, - // we should call that function to Upgrade it - for version, upgrade := range v.r.upgradeTable { - if strings.HasPrefix(key, version) { - // We should run this Upgrade function - // The user of this function must update the key - // based on the version returned in this - // versioned object! - return upgrade(key, &result) + return &result, nil +} + +// Get gets and upgrades data stored in the key/value store +// Make sure to inspect the version returned in the versioned object +func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) { + key = v.makeKey(key) + jww.TRACE.Printf("Get %p with key %v", v.r.data, key) + // Get raw data + result := &Object{} + err := v.r.data.Get(key, result) + if err != nil { + return nil, err + } + + initialVersion := result.Version + for result.Version<uint64(len(table)){ + oldVersion := result.Version + result, err = table[oldVersion](result) + if err!=nil{ + jww.FATAL.Panicf("failed to upgrade key %s from " + + "version %v, initla version %v", key, oldVersion, + initialVersion) } } - return &result, nil + + if initialVersion<uint64(len(table)){ + //save the upgraded file? + } + + return result, nil } + // delete removes a given key from the data store func (v *KV) Delete(key string) error { - key = v.prefix + key + key = v.makeKey(key) jww.TRACE.Printf("delete %p with key %v", v.r.data, key) return v.r.data.Delete(key) } @@ -114,7 +111,7 @@ func (v *KV) Delete(key string) error { // When calling this, you are responsible for prefixing the key with the correct // type optionally unique id! Call MakeKeyWithPrefix() to do so. func (v *KV) Set(key string, object *Object) error { - key = v.prefix + key + key = v.makeKey(key) jww.TRACE.Printf("Set %p with key %v", v.r.data, key) return v.r.data.Set(key, object) } @@ -132,3 +129,7 @@ func (v *KV) Prefix(prefix string) *KV { func (v *KV) GetFullKey(key string) string { return v.prefix + key } + +func (v *KV)makeKey(key string)string{ + return v.prefix + key +} \ No newline at end of file diff --git a/ud/registered.go b/ud/registered.go index 6c1065177..8191f2667 100644 --- a/ud/registered.go +++ b/ud/registered.go @@ -18,7 +18,7 @@ func (m *Manager) loadRegistered() { var isReg = uint32(0) obj, err := m.storage.Get(isRegisteredKey) if err != nil { - jww.INFO.Printf("Failed to load is registered; "+ + jww.INFO.Printf("Failed to load is registered, "+ "assuming un-registered: %s", err) } else { isReg = binary.BigEndian.Uint32(obj.Data) -- GitLab