mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-07 08:50:59 +08:00
Updated RAFT layer to use new keyspace methods. Fixed API methods for HSET and SINTERCARD to match new key overwriting behaviour.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -616,13 +616,13 @@ func TestEchoVault_HSET(t *testing.T) {
|
|||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "HSET returns error when the target key is not a map",
|
name: "HSET overwrites when the target key is not a map",
|
||||||
key: "key6",
|
key: "key6",
|
||||||
presetValue: "Default preset value",
|
presetValue: "Default preset value",
|
||||||
fieldValuePairs: map[string]string{"field1": "value1"},
|
fieldValuePairs: map[string]string{"field1": "value1"},
|
||||||
hsetFunc: server.HSet,
|
hsetFunc: server.HSet,
|
||||||
want: 0,
|
want: 1,
|
||||||
wantErr: true,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@@ -467,13 +467,12 @@ func TestEchoVault_SINTERCARD(t *testing.T) {
|
|||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Return 0 if any of the keys does not exist",
|
name: "Return error if any of the keys is non-existent",
|
||||||
presetValues: map[string]interface{}{
|
presetValues: map[string]interface{}{
|
||||||
"key11": set.NewSet([]string{"one", "two", "three", "four", "five", "six", "seven", "eight"}),
|
"key11": set.NewSet([]string{"one", "two", "three", "four", "five", "six", "seven", "eight"}),
|
||||||
"key12": "Default value",
|
|
||||||
"key13": set.NewSet([]string{"one"}),
|
"key13": set.NewSet([]string{"one"}),
|
||||||
},
|
},
|
||||||
keys: []string{"key11", "key12", "key13", "non-existent"},
|
keys: []string{"key11", "key12", "key13"},
|
||||||
limit: 0,
|
limit: 0,
|
||||||
want: 0,
|
want: 0,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
|
@@ -190,36 +190,39 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if echovault.isInCluster() {
|
if echovault.isInCluster() {
|
||||||
// TODO: Uncomment this
|
echovault.raft = raft.NewRaft(raft.Opts{
|
||||||
// echovault.raft = raft.NewRaft(raft.Opts{
|
Config: echovault.config,
|
||||||
// Config: echovault.config,
|
GetCommand: echovault.getCommand,
|
||||||
// GetCommand: echovault.getCommand,
|
SetValues: echovault.setValues,
|
||||||
// SetValue: echovault.SetValue,
|
SetExpiry: echovault.setExpiry,
|
||||||
// SetExpiry: echovault.SetExpiry,
|
StartSnapshot: echovault.startSnapshot,
|
||||||
// DeleteKey: echovault.DeleteKey,
|
FinishSnapshot: echovault.finishSnapshot,
|
||||||
// StartSnapshot: echovault.startSnapshot,
|
SetLatestSnapshotTime: echovault.setLatestSnapshot,
|
||||||
// FinishSnapshot: echovault.finishSnapshot,
|
GetHandlerFuncParams: echovault.getHandlerFuncParams,
|
||||||
// SetLatestSnapshotTime: echovault.setLatestSnapshot,
|
DeleteKey: func(key string) error {
|
||||||
// GetHandlerFuncParams: echovault.getHandlerFuncParams,
|
echovault.storeLock.Lock()
|
||||||
// GetState: func() map[string]internal.KeyData {
|
defer echovault.storeLock.Unlock()
|
||||||
// state := make(map[string]internal.KeyData)
|
return echovault.deleteKey(key)
|
||||||
// for k, v := range echovault.getState() {
|
},
|
||||||
// if data, ok := v.(internal.KeyData); ok {
|
GetState: func() map[string]internal.KeyData {
|
||||||
// state[k] = data
|
state := make(map[string]internal.KeyData)
|
||||||
// }
|
for k, v := range echovault.getState() {
|
||||||
// }
|
if data, ok := v.(internal.KeyData); ok {
|
||||||
// return state
|
state[k] = data
|
||||||
// },
|
}
|
||||||
// })
|
}
|
||||||
// echovault.memberList = memberlist.NewMemberList(memberlist.Opts{
|
return state
|
||||||
// Config: echovault.config,
|
},
|
||||||
// HasJoinedCluster: echovault.raft.HasJoinedCluster,
|
})
|
||||||
// AddVoter: echovault.raft.AddVoter,
|
echovault.memberList = memberlist.NewMemberList(memberlist.Opts{
|
||||||
// RemoveRaftServer: echovault.raft.RemoveServer,
|
Config: echovault.config,
|
||||||
// IsRaftLeader: echovault.raft.IsRaftLeader,
|
HasJoinedCluster: echovault.raft.HasJoinedCluster,
|
||||||
// ApplyMutate: echovault.raftApplyCommand,
|
AddVoter: echovault.raft.AddVoter,
|
||||||
// ApplyDeleteKey: echovault.raftApplyDeleteKey,
|
RemoveRaftServer: echovault.raft.RemoveServer,
|
||||||
// })
|
IsRaftLeader: echovault.raft.IsRaftLeader,
|
||||||
|
ApplyMutate: echovault.raftApplyCommand,
|
||||||
|
ApplyDeleteKey: echovault.raftApplyDeleteKey,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// Set up standalone snapshot engine
|
// Set up standalone snapshot engine
|
||||||
echovault.snapshotEngine = snapshot.NewSnapshotEngine(
|
echovault.snapshotEngine = snapshot.NewSnapshotEngine(
|
||||||
|
@@ -116,7 +116,7 @@ func Test_HandleHSET(t *testing.T) {
|
|||||||
expectedError: nil,
|
expectedError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "6. HSET returns error when the target key is not a map",
|
name: "6. HSET overwrites when the target key is not a map",
|
||||||
key: "HsetKey6",
|
key: "HsetKey6",
|
||||||
presetValue: "Default preset value",
|
presetValue: "Default preset value",
|
||||||
command: []string{"HSET", "HsetKey6", "field1", "value1"},
|
command: []string{"HSET", "HsetKey6", "field1", "value1"},
|
||||||
|
@@ -32,11 +32,9 @@ type FSMOpts struct {
|
|||||||
Config config.Config
|
Config config.Config
|
||||||
GetState func() map[string]internal.KeyData
|
GetState func() map[string]internal.KeyData
|
||||||
GetCommand func(command string) (internal.Command, error)
|
GetCommand func(command string) (internal.Command, error)
|
||||||
CreateKeyAndLock func(ctx context.Context, key string) (bool, error)
|
SetValues func(ctx context.Context, entries map[string]interface{}) error
|
||||||
SetValue func(ctx context.Context, key string, value interface{}) error
|
|
||||||
SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool)
|
SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool)
|
||||||
KeyUnlock func(ctx context.Context, key string)
|
DeleteKey func(key string) error
|
||||||
DeleteKey func(ctx context.Context, key string) error
|
|
||||||
StartSnapshot func()
|
StartSnapshot func()
|
||||||
FinishSnapshot func()
|
FinishSnapshot func()
|
||||||
SetLatestSnapshotTime func(msec int64)
|
SetLatestSnapshotTime func(msec int64)
|
||||||
@@ -79,7 +77,7 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "delete-key":
|
case "delete-key":
|
||||||
if err := fsm.options.DeleteKey(ctx, request.Key); err != nil {
|
if err := fsm.options.DeleteKey(request.Key); err != nil {
|
||||||
return internal.ApplyResponse{
|
return internal.ApplyResponse{
|
||||||
Error: err,
|
Error: err,
|
||||||
Response: nil,
|
Response: nil,
|
||||||
@@ -164,14 +162,10 @@ func (fsm *FSM) Restore(snapshot io.ReadCloser) error {
|
|||||||
// Set state
|
// Set state
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
for k, v := range internal.FilterExpiredKeys(time.Now(), data.State) {
|
for k, v := range internal.FilterExpiredKeys(time.Now(), data.State) {
|
||||||
if _, err = fsm.options.CreateKeyAndLock(ctx, k); err != nil {
|
if err = fsm.options.SetValues(ctx, map[string]interface{}{k: v.Value}); err != nil {
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = fsm.options.SetValue(ctx, k, v.Value); err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fsm.options.SetExpiry(ctx, k, v.ExpireAt, false)
|
fsm.options.SetExpiry(ctx, k, v.ExpireAt, false)
|
||||||
fsm.options.KeyUnlock(ctx, k)
|
|
||||||
}
|
}
|
||||||
// Set latest snapshot milliseconds
|
// Set latest snapshot milliseconds
|
||||||
fsm.options.SetLatestSnapshotTime(data.LatestSnapshotMilliseconds)
|
fsm.options.SetLatestSnapshotTime(data.LatestSnapshotMilliseconds)
|
||||||
|
@@ -33,13 +33,11 @@ import (
|
|||||||
|
|
||||||
type Opts struct {
|
type Opts struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
CreateKeyAndLock func(ctx context.Context, key string) (bool, error)
|
SetValues func(ctx context.Context, entries map[string]interface{}) error
|
||||||
SetValue func(ctx context.Context, key string, value interface{}) error
|
|
||||||
SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool)
|
SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool)
|
||||||
KeyUnlock func(ctx context.Context, key string)
|
|
||||||
GetState func() map[string]internal.KeyData
|
GetState func() map[string]internal.KeyData
|
||||||
GetCommand func(command string) (internal.Command, error)
|
GetCommand func(command string) (internal.Command, error)
|
||||||
DeleteKey func(ctx context.Context, key string) error
|
DeleteKey func(key string) error
|
||||||
StartSnapshot func()
|
StartSnapshot func()
|
||||||
FinishSnapshot func()
|
FinishSnapshot func()
|
||||||
SetLatestSnapshotTime func(msec int64)
|
SetLatestSnapshotTime func(msec int64)
|
||||||
@@ -118,10 +116,8 @@ func (r *Raft) RaftInit(ctx context.Context) {
|
|||||||
Config: r.options.Config,
|
Config: r.options.Config,
|
||||||
GetState: r.options.GetState,
|
GetState: r.options.GetState,
|
||||||
GetCommand: r.options.GetCommand,
|
GetCommand: r.options.GetCommand,
|
||||||
CreateKeyAndLock: r.options.CreateKeyAndLock,
|
SetValues: r.options.SetValues,
|
||||||
SetValue: r.options.SetValue,
|
|
||||||
SetExpiry: r.options.SetExpiry,
|
SetExpiry: r.options.SetExpiry,
|
||||||
KeyUnlock: r.options.KeyUnlock,
|
|
||||||
DeleteKey: r.options.DeleteKey,
|
DeleteKey: r.options.DeleteKey,
|
||||||
StartSnapshot: r.options.StartSnapshot,
|
StartSnapshot: r.options.StartSnapshot,
|
||||||
FinishSnapshot: r.options.FinishSnapshot,
|
FinishSnapshot: r.options.FinishSnapshot,
|
||||||
|
Reference in New Issue
Block a user