diff --git a/go.mod b/go.mod index 3c296b8..5fc7b5e 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index fdfc06d..7597e69 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/hashmap/hashmap.go b/hashmap/hashmap.go index d28f05b..0536d1d 100644 --- a/hashmap/hashmap.go +++ b/hashmap/hashmap.go @@ -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" @@ -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 } @@ -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) @@ -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) @@ -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) @@ -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) diff --git a/hashmap/hashmap_test.go b/hashmap/hashmap_test.go index 4397d37..1541181 100644 --- a/hashmap/hashmap_test.go +++ b/hashmap/hashmap_test.go @@ -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) +} diff --git a/malloc/malloc.go b/malloc/malloc.go index 1bef16b..905542a 100644 --- a/malloc/malloc.go +++ b/malloc/malloc.go @@ -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 +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)) }