Skip to content
Snippets Groups Projects
Commit 80edec44 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

added support for keeping old version files

parent a020fe26
No related branches found
No related tags found
No related merge requests found
...@@ -154,6 +154,9 @@ func loadSession(ship *relationship, kv *versioned.KV, ...@@ -154,6 +154,9 @@ func loadSession(ship *relationship, kv *versioned.KV,
return nil, errors.WithMessagef(err, "Failed to load %s", kv.GetFullKey(sessionKey)) return nil, errors.WithMessagef(err, "Failed to load %s", kv.GetFullKey(sessionKey))
} }
obj, err := sessionUpgradeTable.Upgrade(obj)
err = session.unmarshal(obj.Data) err = session.unmarshal(obj.Data)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -9,6 +9,7 @@ package versioned ...@@ -9,6 +9,7 @@ package versioned
import ( import (
"fmt" "fmt"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/ekv" "gitlab.com/elixxir/ekv"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
...@@ -57,8 +58,8 @@ func NewKV(data ekv.KeyValue) *KV { ...@@ -57,8 +58,8 @@ func NewKV(data ekv.KeyValue) *KV {
// Get gets and upgrades data stored in the key/value store // Get gets and upgrades data stored in the key/value store
// Make sure to inspect the version returned in the versioned object // Make sure to inspect the version returned in the versioned object
func (v *KV) Get(key string) (*Object, error) { func (v *KV) Get(key string, version uint64) (*Object, error) {
key = v.makeKey(key) key = v.makeKey(key, version)
jww.TRACE.Printf("Get %p with key %v", v.r.data, key) jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
// Get raw data // Get raw data
result := Object{} result := Object{}
...@@ -69,22 +70,47 @@ func (v *KV) Get(key string) (*Object, error) { ...@@ -69,22 +70,47 @@ func (v *KV) Get(key string) (*Object, error) {
return &result, nil return &result, nil
} }
type UpgradeTable struct{
CurrentVersion uint64
Table []Upgrade
}
// Get gets and upgrades data stored in the key/value store // Get gets and upgrades data stored in the key/value store
// Make sure to inspect the version returned in the versioned object // Make sure to inspect the version returned in the versioned object
func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) { func (v *KV) GetUpgrade(key string, ut UpgradeTable) (*Object, error) {
key = v.makeKey(key) version := ut.CurrentVersion
key = v.makeKey(key, version)
if uint64(len(ut.Table))!=version{
jww.FATAL.Panicf("Cannot get upgrade for %s: table lengh (%d) " +
"does not match current version (%d)", key, len(ut.Table),
version)
}
var result *Object
for ;version>=0;version--{
key = v.makeKey(key, version)
jww.TRACE.Printf("Get %p with key %v", v.r.data, key) jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
// Get raw data // Get raw data
result := &Object{} result = &Object{}
err := v.r.data.Get(key, result) err := v.r.data.Get(key, result)
if err != nil { if err != nil {
return nil, err jww.WARN.Printf("Failed to get keyvalue %s: %s", key, err)
}else{
break
}
}
if version < 0{
return nil, errors.Errorf("Failed to get key and upgrade it for %s", v.makeKey(key, ut.CurrentVersion))
} }
var err error
initialVersion := result.Version initialVersion := result.Version
for result.Version<uint64(len(table)){ for result.Version<uint64(len(ut.Table)){
oldVersion := result.Version oldVersion := result.Version
result, err = table[oldVersion](result) result, err = ut.Table[oldVersion](result)
if err!=nil{ if err!=nil{
jww.FATAL.Panicf("failed to upgrade key %s from " + jww.FATAL.Panicf("failed to upgrade key %s from " +
"version %v, initla version %v", key, oldVersion, "version %v, initla version %v", key, oldVersion,
...@@ -97,8 +123,8 @@ func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) { ...@@ -97,8 +123,8 @@ func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) {
// delete removes a given key from the data store // delete removes a given key from the data store
func (v *KV) Delete(key string) error { func (v *KV) Delete(key string, version uint64) error {
key = v.makeKey(key) key = v.makeKey(key, version)
jww.TRACE.Printf("delete %p with key %v", v.r.data, key) jww.TRACE.Printf("delete %p with key %v", v.r.data, key)
return v.r.data.Delete(key) return v.r.data.Delete(key)
} }
...@@ -106,8 +132,8 @@ func (v *KV) Delete(key string) error { ...@@ -106,8 +132,8 @@ func (v *KV) Delete(key string) error {
// Set upserts new data into the storage // Set upserts new data into the storage
// When calling this, you are responsible for prefixing the key with the correct // When calling this, you are responsible for prefixing the key with the correct
// type optionally unique id! Call MakeKeyWithPrefix() to do so. // type optionally unique id! Call MakeKeyWithPrefix() to do so.
func (v *KV) Set(key string, object *Object) error { func (v *KV) Set(key string, version uint64, object *Object) error {
key = v.makeKey(key) key = v.makeKey(key, version)
jww.TRACE.Printf("Set %p with key %v", v.r.data, key) jww.TRACE.Printf("Set %p with key %v", v.r.data, key)
return v.r.data.Set(key, object) return v.r.data.Set(key, object)
} }
...@@ -122,10 +148,10 @@ func (v *KV) Prefix(prefix string) *KV { ...@@ -122,10 +148,10 @@ func (v *KV) Prefix(prefix string) *KV {
} }
//Returns the key with all prefixes appended //Returns the key with all prefixes appended
func (v *KV) GetFullKey(key string) string { func (v *KV) GetFullKey(key string, version uint64) string {
return v.prefix + key return v.makeKey(key, version)
} }
func (v *KV)makeKey(key string)string{ func (v *KV)makeKey(key string, version uint64)string{
return v.prefix + key return fmt.Sprintf("%s%s_%d", v.prefix, key, version)
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment