Skip to content

Commit 90bd7fd

Browse files
committed
🎉 cleanup, first release! bump v0.1.0
1 parent 7fcf2e4 commit 90bd7fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+290
-20148
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Changes
2+
=======
3+
4+
#### ver.: 0.1.0 (25.01.2025)
5+
6+
* 🎉 First release!

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ lint: ## Lint the files
1515
test: ## Run unittests
1616
@go test -short ${PKG_LIST} -count=1
1717

18+
.PHONY: bench
19+
bench: ## Run benchmarks
20+
@go test -bench=. ${PKG_LIST}
21+
1822
## Help
1923

2024
.PHONY: help

README.md

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
# sortedmap
1+
# 📚 sortedmap
22

33
`sortedmap` provides an effective sorted map implementation for Go.
4-
Below you will find information about the repository, its usage, and the API with complexity details.
4+
It uses a heap to maintain order and iterators under the hood.
5+
6+
---
7+
8+
[![Build Status](https://github.com/egregors/sortedmap/workflows/build/badge.svg)](https://github.com/egregors/sortedmap/actions)
9+
[![Go Report Card](https://goreportcard.com/badge/github.com/egregors/sortedmap)](https://goreportcard.com/report/github.com/egregors/sortedmap)
10+
[![Coverage Status](https://coveralls.io/repos/github/egregors/sortedmap/badge.svg?branch=main)](https://coveralls.io/github/egregors/sortedmap?branch=main)
11+
[![godoc](https://godoc.org/github.com/egregors/sortedmap?status.svg)](https://godoc.org/github.com/egregors/sortedmap)
12+
513

614
## Features
715

816
* 🚀 Efficient sorted map implementation
917
* 🔧 Customizable sorting by key or value
18+
* 🐈 Zero dependencies
19+
* 📦 Easy to use API (inspired by the stdlib `maps` and `slices` packages)
1020

1121
## Installation
1222

@@ -26,39 +36,100 @@ package main
2636
import (
2737
"fmt"
2838

29-
"github.com/egregors/sortedmap"
39+
sm "github.com/egregors/sortedmap"
3040
)
3141

42+
type Person struct {
43+
Name string
44+
Age int
45+
}
46+
3247
func main() {
33-
sm := sortedmap.NewFromMap(map[string]int{
34-
"Bob": 42,
35-
"Alice": 30,
36-
"Charlie": 25,
37-
}, func(i, j sortedmap.KV[string, int]) bool {
38-
return i.key < j.key
48+
// Create a new map sorted by keys
49+
m := sm.NewFromMap(map[string]int{
50+
"Bob": 31,
51+
"Alice": 26,
52+
"Eve": 84,
53+
}, func(i, j sm.KV[string, int]) bool {
54+
return i.Key < j.Key
55+
})
56+
57+
fmt.Println(m.Collect())
58+
// Output: map[Alice:26 Bob:31 Eve:84]
59+
60+
m.Insert("Charlie", 34)
61+
fmt.Println(m.Collect())
62+
// Output: map[Alice:26 Bob:31 Charlie:34 Eve:84]
63+
64+
m.Delete("Bob")
65+
fmt.Println(m.Collect())
66+
// Output: map[Alice:26 Charlie:34 Eve:84]
67+
68+
// Create a new map sorted by values
69+
m2 := sm.NewFromMap(map[string]Person{
70+
"Bob": {"Bob", 31},
71+
"Alice": {"Alice", 26},
72+
"Eve": {"Eve", 84},
73+
}, func(i, j sm.KV[string, Person]) bool {
74+
return i.Val.Age < j.Val.Age
75+
})
76+
77+
fmt.Println(m2.Collect())
78+
// Output: map[Alice:{Alice 26} Bob:{Bob 31} Eve:{Eve 84}]
79+
80+
// Create a new map sorted by values but if the values are equal, sort by keys
81+
m3 := sm.NewFromMap(map[string]Person{
82+
"Bob": {"Bob", 26},
83+
"Alice": {"Alice", 26},
84+
"Eve": {"Eve", 84},
85+
}, func(i, j sm.KV[string, Person]) bool {
86+
if i.Val.Age == j.Val.Age {
87+
return i.Key < j.Key
88+
}
89+
90+
return i.Val.Age < j.Val.Age
3991
})
4092

41-
fmt.Println(sm.Collect())
93+
fmt.Println(m3.Collect())
94+
// Output: map[Alice:{Alice 26} Bob:{Bob 26} Eve:{Eve 84}]
4295
}
96+
4397
```
4498

4599
## API and Complexity
46100

47-
| Method | Description | Complexity |
48-
|--------------|-------------------------------------------------------------------------|------------|
49-
| `New` | Creates a new `SortedMap` with a custom comparison function | O(1) |
50-
| `NewFromMap` | Creates a new `SortedMap` from an existing map with a custom comparison | O(n log n) |
51-
| `Get` | Retrieves the value associated with a key | O(1) |
52-
| `Delete` | Removes a key-value pair from the map | O(n) |
53-
| `All` | Returns a sequence of all key-value pairs in the map | O(n log n) |
54-
| `Keys` | Returns a sequence of all keys in the map | O(n log n) |
55-
| `Values` | Returns a sequence of all values in the map | O(n log n) |
56-
| `Insert` | Adds or updates a key-value pair in the map | O(log n) |
57-
| `Collect` | Returns a map with the same contents as the `SortedMap` | O(n log n) |
58-
59-
## Contributing
60-
61-
We welcome contributions! Please see the `CONTRIBUTING.md` file for guidelines on how to contribute to this project.
101+
| Method | Description | Complexity |
102+
|--------------|------------------------------------------------------------------|------------|
103+
| `New` | Creates a new `SortedMap` with a comparison function | O(1) |
104+
| `NewFromMap` | Creates a new `SortedMap` from an existing map with a comparison | O(n log n) |
105+
| `Get` | Retrieves the value associated with a key | O(1) |
106+
| `Delete` | Removes a key-value pair from the map | O(n) |
107+
| `All` | Returns a sequence of all key-value pairs in the map | O(n log n) |
108+
| `Keys` | Returns a sequence of all keys in the map | O(n log n) |
109+
| `Values` | Returns a sequence of all values in the map | O(n log n) |
110+
| `Insert` | Adds or updates a key-value pair in the map | O(log n) |
111+
| `Collect` | Returns a map with the same contents as the `SortedMap` | O(n log n) |
112+
113+
## Benchmarks
114+
115+
```shell
116+
goos: darwin
117+
goarch: arm64
118+
pkg: github.com/egregors/sortedmap
119+
cpu: Apple M1 Max
120+
BenchmarkNew-10 165633163 7.143 ns/op
121+
BenchmarkNewFromMap-10 406633 2806 ns/op
122+
BenchmarkSortedMap_Get-10 154206174 7.849 ns/op
123+
BenchmarkSortedMap_All-10 1000000000 0.3153 ns/op
124+
BenchmarkSortedMap_Collect-10 627693 1929 ns/op
125+
BenchmarkSortedMap_Keys-10 1000000000 0.3150 ns/op
126+
BenchmarkSortedMap_Values-10 1000000000 0.3233 ns/op
127+
BenchmarkSortedMap_Insert-10 6625201 182.0 ns/op
128+
BenchmarkSortedMap_Delete-10 3301149 373.4 ns/op
129+
PASS
130+
131+
```
132+
62133

63134
## License
64135

go.mod

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
11
module github.com/egregors/sortedmap
22

33
go 1.23
4-
5-
require github.com/stretchr/testify v1.10.0
6-
7-
require (
8-
github.com/davecgh/go-spew v1.1.1 // indirect
9-
github.com/pmezard/go-difflib v1.0.0 // indirect
10-
gopkg.in/yaml.v3 v3.0.1 // indirect
11-
)

go.sum

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +0,0 @@
1-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2-
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5-
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
6-
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
7-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
8-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
9-
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
10-
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

kvheap.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package sortedmap
22

33
type KV[K comparable, V any] struct {
4-
key K
5-
val V
4+
Key K
5+
Val V
66
}
77

88
type kvHeap[K comparable, V any] struct {

ptr/ptr.go

Lines changed: 0 additions & 5 deletions
This file was deleted.

sortedmap.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ func (sm *SortedMap[Map, K, V]) Get(key K) (V, bool) {
4949
// The complexity is O(n) where n = len(sm.h.xs)
5050
func (sm *SortedMap[Map, K, V]) Delete(key K) (val *V, existed bool) {
5151
delete(sm.m, key)
52-
// TODO: to remove the element from the heap, we need to full scan it with O(n) complexity.
52+
// TODO: in order to remove the element from the heap, we need to full scan it with O(n).
5353
// probably we can use a map to store the index of the element in the heap, but the problem
54-
// is that elements indexes will constantly change as we remove or add elements.
54+
// is that element indexes will constantly change as we remove or add elements.
5555
for i, el := range sm.h.xs {
56-
if el.key == key {
57-
val = &el.val
56+
if el.Key == key {
57+
val = &el.Val
5858
heap.Remove(sm.h, i)
5959

6060
return val, true
@@ -70,7 +70,7 @@ func (sm *SortedMap[Map, K, V]) All() iter.Seq2[K, V] {
7070
tempHeap := *sm.h
7171
for tempHeap.Len() > 0 {
7272
el := heap.Pop(&tempHeap).(KV[K, V])
73-
if !yield(el.key, el.val) {
73+
if !yield(el.Key, el.Val) {
7474
return
7575
}
7676
}
@@ -83,7 +83,7 @@ func (sm *SortedMap[Map, K, V]) Keys() iter.Seq[K] {
8383
tempHeap := *sm.h
8484
for tempHeap.Len() > 0 {
8585
el := heap.Pop(&tempHeap).(KV[K, V])
86-
if !yield(el.key) {
86+
if !yield(el.Key) {
8787
return
8888
}
8989
}
@@ -96,7 +96,7 @@ func (sm *SortedMap[Map, K, V]) Values() iter.Seq[V] {
9696
tempHeap := *sm.h
9797
for tempHeap.Len() > 0 {
9898
el := heap.Pop(&tempHeap).(KV[K, V])
99-
if !yield(el.val) {
99+
if !yield(el.Val) {
100100
return
101101
}
102102
}

0 commit comments

Comments
 (0)