Implemented scaffolding for set data type

This commit is contained in:
Kelvin Clement Mwinuka
2023-12-22 20:25:40 +03:00
parent 181844c7eb
commit a9c26ff328
4 changed files with 376 additions and 3 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/kelvinmwinuka/memstore/src/modules/list" "github.com/kelvinmwinuka/memstore/src/modules/list"
"github.com/kelvinmwinuka/memstore/src/modules/ping" "github.com/kelvinmwinuka/memstore/src/modules/ping"
"github.com/kelvinmwinuka/memstore/src/modules/pubsub" "github.com/kelvinmwinuka/memstore/src/modules/pubsub"
"github.com/kelvinmwinuka/memstore/src/modules/set"
str "github.com/kelvinmwinuka/memstore/src/modules/string" str "github.com/kelvinmwinuka/memstore/src/modules/string"
"io" "io"
"log" "log"
@@ -355,6 +356,7 @@ func (server *Server) LoadModules(ctx context.Context) {
server.LoadCommands(list.NewModule()) server.LoadCommands(list.NewModule())
server.LoadCommands(str.NewModule()) server.LoadCommands(str.NewModule())
server.LoadCommands(etc.NewModule()) server.LoadCommands(etc.NewModule())
server.LoadCommands(set.NewModule())
} }
func (server *Server) Start(ctx context.Context) { func (server *Server) Start(ctx context.Context) {

View File

@@ -16,8 +16,6 @@ type Plugin struct {
description string description string
} }
var GetModule Plugin
func (p Plugin) Name() string { func (p Plugin) Name() string {
return p.name return p.name
} }
@@ -120,7 +118,7 @@ func NewModule() Plugin {
Command: "mget", Command: "mget",
Categories: []string{utils.ReadCategory, utils.FastCategory}, Categories: []string{utils.ReadCategory, utils.FastCategory},
Description: "(MGET key1 [key2]) Get multiple values from the specified keys.", Description: "(MGET key1 [key2]) Get multiple values from the specified keys.",
Sync: true, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE) return nil, errors.New(utils.WRONG_ARGS_RESPONSE)

View File

@@ -1 +1,334 @@
package set package set
import (
"context"
"errors"
"github.com/kelvinmwinuka/memstore/src/utils"
"net"
"strings"
)
type Plugin struct {
name string
commands []utils.Command
categories []string
description string
}
func (p Plugin) Name() string {
return p.name
}
func (p Plugin) Commands() []utils.Command {
return p.commands
}
func (p Plugin) Description() string {
return p.description
}
func (p Plugin) HandleCommand(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
switch strings.ToLower(cmd[0]) {
default:
return nil, errors.New("command unknown")
case "sadd":
return handleSADD(ctx, cmd, server)
case "scard":
return handleSCARD(ctx, cmd, server)
case "sdiff":
return handleSDIFF(ctx, cmd, server)
case "sdiffstore":
return handleSDIFFSTORE(ctx, cmd, server)
case "sinter":
return handleSINTERSTORE(ctx, cmd, server)
case "sintercard":
return handleSINTERCARD(ctx, cmd, server)
case "sinterstore":
return handleSINTERSTORE(ctx, cmd, server)
case "sismember":
return handleSISMEMBER(ctx, cmd, server)
case "smembers":
return handleSMEMBERS(ctx, cmd, server)
case "smismember":
return handleSMISMEMBER(ctx, cmd, server)
case "smove":
return handleSMOVE(ctx, cmd, server)
case "spop":
return handleSPOP(ctx, cmd, server)
case "srandmember":
return handleSRANDMEMBER(ctx, cmd, server)
case "srem":
return handleSREM(ctx, cmd, server)
case "sunion":
return handleSUNION(ctx, cmd, server)
case "sunionstore":
return handleSUNIONSTORE(ctx, cmd, server)
}
}
func handleSADD(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SADD not implemented")
}
func handleSCARD(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SCARD not implemented")
}
func handleSDIFF(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SDIFF not implemented")
}
func handleSDIFFSTORE(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SDIFFSTORE not implemented")
}
func handleSINTER(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SINTER not implemented")
}
func handleSINTERCARD(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SINTERCARD not implemented")
}
func handleSINTERSTORE(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SINTERSTORE not implemented")
}
func handleSISMEMBER(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SISMEMBER not implemented")
}
func handleSMEMBERS(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SMEMBERS not implemented")
}
func handleSMISMEMBER(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SMISMEMBER not implemented")
}
func handleSMOVE(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SMOVE not implemented")
}
func handleSPOP(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SPOP not implemented")
}
func handleSRANDMEMBER(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SRANDMEMBER not implemented")
}
func handleSREM(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SREM not implemented")
}
func handleSUNION(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SUNION not implemented")
}
func handleSUNIONSTORE(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("SUNIONSTORE not implemented")
}
func NewModule() Plugin {
GetModule := Plugin{
name: "SetCommands",
commands: []utils.Command{
{
Command: "sadd",
Categories: []string{},
Description: "(SADD key member [member...]) Add one or more members to the set.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "scard",
Categories: []string{},
Description: "(SCARD key) Returns the cardinality of the set.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "sdiff",
Categories: []string{},
Description: "(SDIFF key [key...]) Returns the difference between all the sets in the given keys.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sdiffstore",
Categories: []string{},
Description: "(SDIFFSTORE destination key [key...]) Stores the difference between all the sets at the destination key.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sinter",
Categories: []string{},
Description: "(SINTER key [key...]) Returns the intersection of multiple sets.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sintercard",
Categories: []string{},
Description: "(SINTERCARD key [key...]) Returns the cardinality of the intersection between multiple sets.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sinterstore",
Categories: []string{},
Description: "(SINTERSTORE destination key [key...]) Stores the intersection of multiple sets at the destination key.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sismember",
Categories: []string{},
Description: "(SISMEMBER key member) Returns if member is contained in the set.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "smembers",
Categories: []string{},
Description: "(SMEMBERS key) Returns all members of a set.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "smismember",
Categories: []string{},
Description: "(SMISMEMBER key member [member...]) Returns if multiple members are in the set.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "smove",
Categories: []string{},
Description: "(SMOVE source destination member) Moves a member from source set to destination set.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:3], nil
},
},
{
Command: "spop",
Categories: []string{},
Description: "(SPOP key [count]) Returns and removes one or more random members from the set.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "srandmember",
Categories: []string{},
Description: "(SRANDMEMBER key [count]) Returns one or more random members from the set without removing them.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "srem",
Categories: []string{},
Description: "(SREM key member [member...]) Remove one or more members from a set.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return []string{cmd[1]}, nil
},
},
{
Command: "sunion",
Categories: []string{},
Description: "(SUNION key [key...]) Returns the members of the set resulting from the union of the provided sets.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
{
Command: "sunionstore",
Categories: []string{},
Description: "(SUNIONSTORE destination key [key...]) Stores the union of the given sets into destination.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
}
return cmd[1:], nil
},
},
},
description: "Handle commands for sets",
}
return GetModule
}

View File

@@ -1 +1,41 @@
package set package set
type Set struct {
members map[interface{}]int
}
func NewSet(elems []interface{}) *Set {
return &Set{}
}
func (set *Set) Add(elems []interface{}) int {
return 0
}
func (set *Set) Remove(elems interface{}) int {
return 0
}
func (set *Set) Pop(count int) []interface{} {
return []interface{}{}
}
func (set *Set) Contains(v interface{}) bool {
return false
}
func (set *Set) Union(other []*Set) Set {
return Set{}
}
func (set *Set) Intersection(other []*Set) Set {
return Set{}
}
func (set *Set) Subtract(other []*Set) Set {
return Set{}
}
func (set *Set) Move(other *Set) bool {
return false
}