Skip to content

Commit

Permalink
feat: hash use swissmap
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Nov 10, 2024
1 parent c2eb8ca commit 3cf6621
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 54 deletions.
3 changes: 1 addition & 2 deletions ae.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func GetMsTime() int64 {
func (loop *AeLoop) AddTimeEvent(mask TeType, interval int64, proc TimeProc, extra interface{}) int {
id := loop.timeEventNextId
loop.timeEventNextId++
te := AeTimeEvent{
loop.TimeEvents = &AeTimeEvent{
id: id,
mask: mask,
interval: interval,
Expand All @@ -109,7 +109,6 @@ func (loop *AeLoop) AddTimeEvent(mask TeType, interval int64, proc TimeProc, ext
extra: extra,
next: loop.TimeEvents,
}
loop.TimeEvents = &te
return id
}

Expand Down
6 changes: 0 additions & 6 deletions aof.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ import (
"github.com/tidwall/mmap"
)

const (
KB = 1024
MB = 1024 * KB
GB = 1024 * MB
)

// Aof manages an append-only file system for storing data.
type Aof struct {
file *os.File
Expand Down
18 changes: 5 additions & 13 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,15 @@ func setCommand(writer *resp.Writer, args []resp.RESP) {

func incrCommand(writer *resp.Writer, args []resp.RESP) {
key := args[0].ToString()

object, ttl := db.dict.Get(key)
if ttl == KEY_NOT_EXIST {
db.dict.Set(key, 1)
writer.WriteInteger(1)
return
object = 0
}

switch v := object.(type) {
case int:
num := v + 1
writer.WriteInteger(num)
db.dict.Set(key, num)

case []byte:
// conv to integer
num, err := resp.RESP(v).ToInt()
Expand All @@ -171,7 +166,6 @@ func incrCommand(writer *resp.Writer, args []resp.RESP) {
num++
strconv.AppendInt(v[:0], int64(num), 10)
writer.WriteInteger(num)

default:
writer.WriteError(errWrongType)
}
Expand Down Expand Up @@ -630,16 +624,14 @@ func fetch[T any](key []byte, new func() T, setnx ...bool) (T, error) {
if len(setnx) > 0 && setnx[0] {
switch data := object.(type) {
case *hash.ZipMap:
if data.Len() < 256 {
break
if data.Len() >= 256 {
db.dict.Set(string(key), data.ToMap())
}
db.dict.Set(string(key), data.ToMap())

case *hash.ZipSet:
if data.Len() < 512 {
break
if data.Len() >= 512 {
db.dict.Set(string(key), data.ToSet())
}
db.dict.Set(string(key), data.ToSet())
}
}
return v, nil
Expand Down
6 changes: 6 additions & 0 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ const (
KEY_NOT_EXIST = -2
)

const (
KB = 1024
MB = 1024 * KB
GB = 1024 * MB
)

// type2c is objectType to new encoder.
var type2c = map[ObjectType]func() iface.Encoder{
TypeMap: func() iface.Encoder { return hash.NewMap() },
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/alicebob/miniredis/v2 v2.33.0
github.com/bytedance/sonic v1.12.4
github.com/chen3feng/stl4go v0.1.1
github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964
github.com/deckarep/golang-set/v2 v2.6.0
github.com/redis/go-redis/v9 v9.7.0
github.com/rs/zerolog v1.33.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo=
github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA=
Expand All @@ -19,6 +21,8 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964 h1:Ew0znI2JatzKy52N1iS5muUsHkf2UJuhocH7uFW7jjs=
github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
38 changes: 21 additions & 17 deletions internal/hash/map.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package hash

import (
"bytes"
"github.com/cockroachdb/swiss"
"github.com/xgzlucario/rotom/internal/iface"
"github.com/xgzlucario/rotom/internal/resp"
)
Expand All @@ -17,46 +19,48 @@ type MapI interface {
var _ MapI = (*Map)(nil)

type Map struct {
data map[string][]byte
data *swiss.Map[string, []byte]
}

func NewMap() *Map {
return &Map{make(map[string][]byte, 256)}
return &Map{
data: swiss.New[string, []byte](256),
}
}

func (m *Map) Get(key string) ([]byte, bool) {
val, ok := m.data[key]
return val, ok
return m.data.Get(key)
}

func (m *Map) Set(key string, val []byte) bool {
_, ok := m.data[key]
m.data[key] = val
_, ok := m.data.Get(key)
m.data.Put(key, val)
return !ok
}

func (m *Map) Remove(key string) bool {
_, ok := m.data[key]
delete(m.data, key)
_, ok := m.data.Get(key)
m.data.Delete(key)
return ok
}

func (m *Map) Len() int {
return len(m.data)
return m.data.Len()
}

func (m *Map) Scan(fn func(key string, val []byte)) {
for key, val := range m.data {
func (m *Map) Scan(fn func(string, []byte)) {
m.data.All(func(key string, val []byte) bool {
fn(key, val)
}
return true
})
}

func (m *Map) Encode(writer *resp.Writer) error {
writer.WriteArrayHead(len(m.data))
for k, v := range m.data {
writer.WriteArrayHead(m.Len())
m.Scan(func(k string, v []byte) {
writer.WriteBulkString(k)
writer.WriteBulk(v)
}
})
return nil
}

Expand All @@ -65,7 +69,7 @@ func (m *Map) Decode(reader *resp.Reader) error {
if err != nil {
return err
}
m.data = make(map[string][]byte, n*2)
m.data = swiss.New[string, []byte](n * 2)
for range n {
key, err := reader.ReadBulk()
if err != nil {
Expand All @@ -75,7 +79,7 @@ func (m *Map) Decode(reader *resp.Reader) error {
if err != nil {
return err
}
m.data[string(key)] = val
m.data.Put(string(key), bytes.Clone(val))
}
return nil
}
29 changes: 15 additions & 14 deletions internal/zset/zset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package zset

import (
"cmp"
"github.com/cockroachdb/swiss"
"github.com/xgzlucario/rotom/internal/iface"
"github.com/xgzlucario/rotom/internal/resp"

Expand All @@ -25,42 +26,41 @@ func nodeCompare(a, b node) int {
}

type ZSet struct {
m map[string]float64
m *swiss.Map[string, float64]
skl *stl4go.SkipList[node, struct{}]
}

func New() *ZSet {
return &ZSet{
m: make(map[string]float64),
m: swiss.New[string, float64](8),
skl: stl4go.NewSkipListFunc[node, struct{}](nodeCompare),
}
}

func (z *ZSet) Get(key string) (float64, bool) {
val, ok := z.m[key]
return val, ok
return z.m.Get(key)
}

func (z *ZSet) Set(key string, score float64) bool {
old, ok := z.m[key]
old, ok := z.m.Get(key)
if ok {
// same
if score == old {
return false
}
z.skl.Remove(node{key, old})
}
z.m[key] = score
z.m.Put(key, score)
z.skl.Insert(node{key, score}, struct{}{})
return !ok
}

func (z *ZSet) Remove(key string) bool {
score, ok := z.m[key]
score, ok := z.m.Get(key)
if !ok {
return false
}
delete(z.m, key)
z.m.Delete(key)
z.skl.Remove(node{key, score})
return true
}
Expand All @@ -71,13 +71,13 @@ func (z *ZSet) PopMin() (key string, score float64) {
score = n.score
return false
})
delete(z.m, key)
z.m.Delete(key)
z.skl.Remove(node{key, score})
return
}

func (z *ZSet) Rank(key string) (int, float64) {
score, ok := z.m[key]
score, ok := z.m.Get(key)
if !ok {
return -1, 0
}
Expand All @@ -101,15 +101,16 @@ func (z *ZSet) Range(start, stop int, fn func(key string, score float64)) {
}

func (z *ZSet) Len() int {
return len(z.m)
return z.m.Len()
}

func (z *ZSet) Encode(writer *resp.Writer) error {
writer.WriteArrayHead(z.Len())
for k, s := range z.m {
z.m.All(func(k string, s float64) bool {
writer.WriteBulkString(k)
writer.WriteFloat(s)
}
return true
})
return nil
}

Expand All @@ -129,7 +130,7 @@ func (z *ZSet) Decode(reader *resp.Reader) error {
}
key := string(buf)
z.skl.Insert(node{key, score}, struct{}{})
z.m[key] = score
z.m.Put(key, score)
}
return nil
}
2 changes: 1 addition & 1 deletion net.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"golang.org/x/sys/unix"
)

const BACKLOG int = 511
const BACKLOG int = 64

func Accept(fd int) (int, error) {
nfd, _, err := unix.Accept(fd)
Expand Down
2 changes: 1 addition & 1 deletion rotom.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func AcceptHandler(loop *AeLoop, fd int, _ interface{}) {
log.Error().Msgf("accept err: %v", err)
return
}
log.Info().Msgf("accept new client fd: %d", fd)
log.Info().Msgf("accept new client fd: %d", cfd)
client := &Client{
fd: cfd,
replyWriter: resp.NewWriter(WriteBufSize),
Expand Down

0 comments on commit 3cf6621

Please sign in to comment.