Skip to content

Commit

Permalink
feat: use maphash instead of hashstructure
Browse files Browse the repository at this point in the history
  • Loading branch information
joetifa2003 committed Sep 7, 2024
1 parent 3c45a26 commit e21dc7f
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 67 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ module github.com/joetifa2003/mm-go
go 1.20

require (
github.com/dolthub/maphash v0.1.0
github.com/ebitengine/purego v0.4.0-alpha.4
github.com/stretchr/testify v1.8.1
golang.org/x/sys v0.7.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.7.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ=
github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4=
github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes=
github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
24 changes: 7 additions & 17 deletions hashmap/hashmap.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package hashmap

import (
"github.com/mitchellh/hashstructure/v2"
"github.com/dolthub/maphash"

"github.com/joetifa2003/mm-go"
"github.com/joetifa2003/mm-go/linkedlist"
Expand All @@ -19,12 +19,14 @@ type pair[K comparable, V any] struct {
type Hashmap[K comparable, V any] struct {
pairs *vector.Vector[*linkedlist.LinkedList[pair[K, V]]]
totalTaken int
mh maphash.Hasher[K]
}

// New creates a new Hashmap with key of type K and value of type V
func New[K comparable, V any]() *Hashmap[K, V] {
hm := mm.Alloc[Hashmap[K, V]]()
hm.pairs = vector.New[*linkedlist.LinkedList[pair[K, V]]](8)
hm.mh = maphash.NewHasher[K]()
return hm
}

Expand Down Expand Up @@ -59,10 +61,7 @@ func (hm *Hashmap[K, V]) Insert(key K, value V) {
hm.extend()
}

hash, err := hashstructure.Hash(key, hashstructure.FormatV2, nil)
if err != nil {
panic(err)
}
hash := hm.mh.Hash(key)

idx := int(hash % uint64(hm.pairs.Len()))
pairs := hm.pairs.At(idx)
Expand All @@ -77,10 +76,7 @@ func (hm *Hashmap[K, V]) Insert(key K, value V) {

// Get takes key K and return value V
func (hm *Hashmap[K, V]) Get(key K) (value V, exists bool) {
hash, err := hashstructure.Hash(key, hashstructure.FormatV2, nil)
if err != nil {
panic(err)
}
hash := hm.mh.Hash(key)

idx := int(hash % uint64(hm.pairs.Len()))
pairs := hm.pairs.At(idx)
Expand All @@ -100,10 +96,7 @@ func (hm *Hashmap[K, V]) Get(key K) (value V, exists bool) {

// GetPtr takes key K and return a pointer to value V
func (hm *Hashmap[K, V]) GetPtr(key K) (value *V, exists bool) {
hash, err := hashstructure.Hash(key, hashstructure.FormatV2, nil)
if err != nil {
panic(err)
}
hash := hm.mh.Hash(key)

idx := int(hash % uint64(hm.pairs.Len()))
pairs := hm.pairs.At(idx)
Expand Down Expand Up @@ -170,10 +163,7 @@ func (hm *Hashmap[K, V]) Keys() []K {

// Delete delete value with key K
func (hm *Hashmap[K, V]) Delete(key K) {
hash, err := hashstructure.Hash(key, hashstructure.FormatV2, nil)
if err != nil {
panic(err)
}
hash := hm.mh.Hash(key)

idx := int(hash % uint64(hm.pairs.Len()))
pairs := hm.pairs.At(idx)
Expand Down
24 changes: 11 additions & 13 deletions hashmap/hashmap_test.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
package hashmap_test

import (
"runtime"
"testing"

"github.com/joetifa2003/mm-go/hashmap"
"github.com/joetifa2003/mm-go/mmstring"
)

const TIMES = 5000

func BenchmarkHashmap(b *testing.B) {
func BenchmarkHashmapGo(b *testing.B) {
for i := 0; i < b.N; i++ {
h := hashmap.New[int, *mmstring.MMString]()
h := newMap()

for i := 0; i < TIMES; i++ {
h.Insert(i, mmstring.From("foo bar"))
h[i] = i
}

h.Free()
runtime.GC()
}
}

func BenchmarkHashmapGo(b *testing.B) {
func BenchmarkHashmap(b *testing.B) {
for i := 0; i < b.N; i++ {
h := map[string]string{}
h := hashmap.New[int, int]()

for i := 0; i < TIMES; i++ {
h["foo"] = "foo bar"
h.Insert(i, i)
}

_ = h
runtime.GC()
h.Free()
}
}

func newMap() map[int]int {
return make(map[int]int)
}
65 changes: 32 additions & 33 deletions malloc/malloc.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,50 @@
package malloc

import (
"fmt"
"runtime"
"unsafe"

"github.com/ebitengine/purego"
)

var calloc func(n int, size int) unsafe.Pointer
var realloc func(ptr unsafe.Pointer, size int) unsafe.Pointer
var free func(ptr unsafe.Pointer)

func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
case "windows":
return "ucrtbase.dll"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}

func init() {
libc, err := openLibrary(getSystemLibrary())
if err != nil {
panic(err)
}
purego.RegisterLibFunc(&calloc, libc, "calloc")
purego.RegisterLibFunc(&realloc, libc, "realloc")
purego.RegisterLibFunc(&free, libc, "free")
}
// #include <stdlib.h>
import "C"

// var calloc func(n int, size int) unsafe.Pointer
// var realloc func(ptr unsafe.Pointer, size int) unsafe.Pointer
// var free func(ptr unsafe.Pointer)

// func getSystemLibrary() string {
// switch runtime.GOOS {
// case "darwin":
// return "/usr/lib/libSystem.B.dylib"
// case "linux":
// return "libc.so.6"
// case "windows":
// return "ucrtbase.dll"
// default:
// panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
// }
// }
//
// func init() {
// libc, err := openLibrary(getSystemLibrary())
// if err != nil {
// panic(err)
// }
// purego.RegisterLibFunc(&calloc, libc, "calloc")
// purego.RegisterLibFunc(&realloc, libc, "realloc")
// purego.RegisterLibFunc(&free, libc, "free")
// }

// CMalloc raw binding to c calloc(1, size)
func Malloc(size int) unsafe.Pointer {
return calloc(1, size)
return C.calloc(1, C.size_t(size))
}

// CMalloc raw binding to c free
func Free(ptr unsafe.Pointer) {
free(ptr)
C.free(ptr)
}

// CMalloc raw binding to c realloc
func Realloc(ptr unsafe.Pointer, size int) unsafe.Pointer {
return realloc(ptr, size)
return C.realloc(ptr, C.size_t(size))
}

0 comments on commit e21dc7f

Please sign in to comment.