Skip to content

Commit

Permalink
fix some issues with commands and data strcutures
Browse files Browse the repository at this point in the history
  • Loading branch information
devmangel committed Sep 2, 2024
1 parent b1b0619 commit fb7a7cc
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 89 deletions.
6 changes: 3 additions & 3 deletions examples/basic_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ func main() {
getCmd := commands.NewGetStringCommand(ht)

// Establecer un valor en la tabla hash
setCmd.Execute("key1", "value1")
setCmd.Execute("Miguel", "30")

// Recuperar el valor de la tabla hash
value, _ := getCmd.Execute("key1")
fmt.Printf("GET key1: %s\n", value)
value, _ := getCmd.Execute("Miguel")
fmt.Printf("GET Miguel: %s\n", value)

// Mostrar el valor esperado
// Output: GET key1: value1
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/devmangel/Yasmine

go 1.23.0

require github.com/yuin/gopher-lua v1.1.1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
5 changes: 5 additions & 0 deletions internal/core/commands/base_command.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package commands

import "errors"

// Command es una interfaz que todos los comandos deben implementar.
type Command interface {
Execute(args ...interface{}) (interface{}, error)
Expand All @@ -20,3 +22,6 @@ func (bc *BaseCommand) Name() string {
func (bc *BaseCommand) Execute(args ...interface{}) (interface{}, error) {
return nil, nil
}

// ErrInvalidArguments se devuelve cuando los argumentos pasados a un comando no son válidos.
var ErrInvalidArguments = errors.New("invalid arguments provided")
4 changes: 2 additions & 2 deletions internal/core/commands/list_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (cmd *LPopCommand) Execute(args ...interface{}) (interface{}, error) {
return nil, nil
}

firstNode := cmd.list.head
firstNode := cmd.list.Head
cmd.list.Remove(firstNode)
return firstNode.Value, nil
}
Expand All @@ -95,7 +95,7 @@ func (cmd *RPopCommand) Execute(args ...interface{}) (interface{}, error) {
return nil, nil
}

lastNode := cmd.list.tail
lastNode := cmd.list.Tail
cmd.list.Remove(lastNode)
return lastNode.Value, nil
}
2 changes: 1 addition & 1 deletion internal/core/commands/sorted_set_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (cmd *ZAddCommand) Execute(args ...interface{}) (interface{}, error) {
}

member := args[1]
cmd.sortedSet.Add(score, member)
cmd.sortedSet.Add(member, score)

return "OK", nil
}
Expand Down
56 changes: 28 additions & 28 deletions internal/core/data_structures/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ package data_structures

import "sync"

// List representa una lista enlazada doblemente segura para concurrencia.
type List struct {
head *Node
tail *Node
size int
lock sync.RWMutex
}

// Node representa un nodo en la lista enlazada.
type Node struct {
value interface{}
Value interface{}
prev *Node
next *Node
}

// NewList crea una nueva instancia de List.
// List representa una lista doblemente enlazada.
type List struct {
Head *Node // Exportado
Tail *Node // Exportado
size int
lock sync.RWMutex
}

// NewList crea una nueva lista vacía.
func NewList() *List {
return &List{}
}
Expand All @@ -28,16 +28,16 @@ func (l *List) Append(value interface{}) {
defer l.lock.Unlock()

newNode := &Node{
value: value,
Value: value,
}

if l.tail == nil {
l.head = newNode
l.tail = newNode
if l.Tail == nil {
l.Head = newNode
l.Tail = newNode
} else {
newNode.prev = l.tail
l.tail.next = newNode
l.tail = newNode
newNode.prev = l.Tail
l.Tail.next = newNode
l.Tail = newNode
}
l.size++
}
Expand All @@ -48,16 +48,16 @@ func (l *List) Prepend(value interface{}) {
defer l.lock.Unlock()

newNode := &Node{
value: value,
Value: value,
}

if l.head == nil {
l.head = newNode
l.tail = newNode
if l.Head == nil {
l.Head = newNode
l.Tail = newNode
} else {
newNode.next = l.head
l.head.prev = newNode
l.head = newNode
newNode.next = l.Head
l.Head.prev = newNode
l.Head = newNode
}
l.size++
}
Expand All @@ -70,13 +70,13 @@ func (l *List) Remove(node *Node) {
if node.prev != nil {
node.prev.next = node.next
} else {
l.head = node.next
l.Head = node.next
}

if node.next != nil {
node.next.prev = node.prev
} else {
l.tail = node.prev
l.Tail = node.prev
}

l.size--
Expand All @@ -94,9 +94,9 @@ func (l *List) Find(value interface{}) *Node {
l.lock.RLock()
defer l.lock.RUnlock()

current := l.head
current := l.Head
for current != nil {
if current.value == value {
if current.Value == value {
return current
}
current = current.next
Expand Down
113 changes: 58 additions & 55 deletions internal/core/data_structures/sorted_set.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,85 @@
package data_structures

import (
"sort"
"sync"
)

// SortedSet representa un conjunto de elementos únicos que están ordenados.
// SortedSet representa un conjunto ordenado donde cada elemento tiene una puntuación asociada.
type SortedSet struct {
elements []interface{}
items map[interface{}]float64
comparator func(a, b interface{}) bool
lock sync.RWMutex
}

// NewSortedSet crea una nueva instancia de SortedSet.
// El comparator es una función que define el orden de los elementos.
func NewSortedSet(comparator func(a, b interface{}) bool) *SortedSet {
return &SortedSet{
elements: []interface{}{},
items: make(map[interface{}]float64),
comparator: comparator,
}
}

// Add añade un elemento al conjunto ordenado.
// La función inserta el elemento en la posición correcta para mantener el orden.
func (s *SortedSet) Add(item interface{}) {
s.lock.Lock()
defer s.lock.Unlock()

idx := sort.Search(len(s.elements), func(i int) bool {
return s.comparator(item, s.elements[i])
})

if idx < len(s.elements) && s.elements[idx] == item {
return // El elemento ya está presente
}

s.elements = append(s.elements[:idx], append([]interface{}{item}, s.elements[idx:]...)...)
// Add añade un nuevo elemento con su puntuación al conjunto ordenado.
func (ss *SortedSet) Add(value interface{}, score float64) {
ss.items[value] = score
}

// Remove elimina un elemento del conjunto ordenado.
func (s *SortedSet) Remove(item interface{}) {
s.lock.Lock()
defer s.lock.Unlock()
func (ss *SortedSet) Remove(value interface{}) {
delete(ss.items, value)
}

idx := sort.Search(len(s.elements), func(i int) bool {
return s.elements[i] == item
})
// Range devuelve un slice de elementos en un rango específico.
func (ss *SortedSet) Range(start, end int) []interface{} {
var result []interface{}

for value := range ss.items {
result = append(result, value)
}

if idx < len(s.elements) && s.elements[idx] == item {
s.elements = append(s.elements[:idx], s.elements[idx+1:]...)
// Ordenar los resultados usando el comparador proporcionado
sortedResult := ss.sort(result)

// Manejo de límites del rango
if start < 0 {
start = 0
}
if end > len(sortedResult) {
end = len(sortedResult)
}

return sortedResult[start:end]
}

// Contains verifica si un elemento está en el conjunto ordenado.
func (s *SortedSet) Contains(item interface{}) bool {
s.lock.RLock()
defer s.lock.RUnlock()
// Score devuelve la puntuación de un elemento en el conjunto ordenado.
func (ss *SortedSet) Score(value interface{}) (float64, bool) {
score, exists := ss.items[value]
return score, exists
}

idx := sort.Search(len(s.elements), func(i int) bool {
return s.elements[i] == item
})
// Método auxiliar para ordenar los resultados.
func (ss *SortedSet) sort(values []interface{}) []interface{} {
// Convertir el mapa en un slice de pares (valor, puntuación) para ordenarlo
type pair struct {
value interface{}
score float64
}

return idx < len(s.elements) && s.elements[idx] == item
}
pairs := make([]pair, 0, len(values))
for _, value := range values {
score := ss.items[value]
pairs = append(pairs, pair{value, score})
}

// Len devuelve la cantidad de elementos en el conjunto ordenado.
func (s *SortedSet) Len() int {
s.lock.RLock()
defer s.lock.RUnlock()
return len(s.elements)
}
// Ordenar los pares según la puntuación utilizando el comparador
for i := 0; i < len(pairs); i++ {
for j := i + 1; j < len(pairs); j++ {
if !ss.comparator(pairs[i].score, pairs[j].score) {
pairs[i], pairs[j] = pairs[j], pairs[i]
}
}
}

// Items devuelve todos los elementos en el conjunto ordenado.
func (s *SortedSet) Items() []interface{} {
s.lock.RLock()
defer s.lock.RUnlock()
// Extraer los valores ordenados
sortedValues := make([]interface{}, len(pairs))
for i, p := range pairs {
sortedValues[i] = p.value
}

items := make([]interface{}, len(s.elements))
copy(items, s.elements)
return items
return sortedValues
}

0 comments on commit fb7a7cc

Please sign in to comment.