{"id":23143286,"url":"https://github.com/aeimer/go-multikeymap","last_synced_at":"2025-05-07T19:46:17.073Z","repository":{"id":263383398,"uuid":"890024196","full_name":"aeimer/go-multikeymap","owner":"aeimer","description":"A go lib which handles maps with multiple keys","archived":false,"fork":false,"pushed_at":"2025-04-08T21:23:24.000Z","size":59,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T21:32:22.857Z","etag":null,"topics":["data-structures","go","go-lib","go-library","golang"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/aeimer/go-multikeymap","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aeimer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-17T20:23:28.000Z","updated_at":"2025-04-08T21:23:17.000Z","dependencies_parsed_at":"2025-01-27T10:22:46.780Z","dependency_job_id":"5d8d954f-7562-4c5f-a9f8-7a26fa75fcc3","html_url":"https://github.com/aeimer/go-multikeymap","commit_stats":null,"previous_names":["aeimer/go-multikeymap"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeimer%2Fgo-multikeymap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeimer%2Fgo-multikeymap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeimer%2Fgo-multikeymap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeimer%2Fgo-multikeymap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aeimer","download_url":"https://codeload.github.com/aeimer/go-multikeymap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252947803,"owners_count":21830039,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-structures","go","go-lib","go-library","golang"],"created_at":"2024-12-17T15:12:58.934Z","updated_at":"2025-05-07T19:46:17.066Z","avatar_url":"https://github.com/aeimer.png","language":"Go","readme":"# go-multikeymap\n\nSee docs: https://pkg.go.dev/github.com/aeimer/go-multikeymap\n\nDISCLAIMER: Until version 1 is reached, the API may change.\n\nA go lib which handles maps with multiple keys.\nBoth data-structures are available in go routine safe (concurrent) and a non-concurrent version.\n\n* **MultiKeyMap** is a data structure based on go native maps.\nIt has a primary key which directly maps to the values.\nThe secondary keys are mapping to the primary key.\nTherefore, the memory consumption is a bit higher than a native map.\nThe access is O(1+1+1) =\u003e O(1) due to the underlying hashmap.\n\n* **BiKeyMap** is a stricter version of MultiKeyMap.\nIt has KeyA and KeyB, both need to be unique.\nThe access is O(1+1) =\u003e O(1) due to the underlying hashmap.\n\n## MultiKeyMap\n\nThis map has a generic primary key and multiple string secondary keys.\nYou can use it like this:\n\n```go\npackage main\n\nimport \"github.com/aeimer/go-multikeymap/multikeymap\"\n\nfunc main() {\n\ttype City struct {\n\t\tName       string\n\t\tPopulation int\n\t}\n\tmm := multikeymap.New[string, City]()\n\t// or: mm := multikeymap.NewConcurrent[string, City]()\n\tmm.Put(\"Berlin\", City{\"Berlin\", 3_500_000})\n\tmm.PutSecondaryKeys(\"Berlin\", \"postcode\", \"10115\", \"10117\", \"10119\")\n\tmm.Get(\"Berlin\")                          // City{\"Berlin\", 3_500_000}\n\tmm.GetBySecondaryKey(\"postcode\", \"10115\") // City{\"Berlin\", 3_500_000}\n}\n```\n\nBenchmark results (`task gotb`):\n\n```\n# =\u003e Non-Concurrent \u003c=                            Iterations\nBenchmarkMultiKeyMapGet/size_100-12                  1430344        824.4 ns/         0 B/op        0 allocs/op\nBenchmarkMultiKeyMapGet/size_1000-12                   36643      33912 ns/op      2880 B/op      900 allocs/op\nBenchmarkMultiKeyMapGet/size_10000-12                   3036     390264 ns/op     38880 B/op     9900 allocs/op\nBenchmarkMultiKeyMapGet/size_100000-12                   261    4601110 ns/op    518882 B/op    99900 allocs/op\n                                                                                 \nBenchmarkMultiKeyMapPut/size_100-12                   888855       1412 ns/op         0 B/op        0 allocs/op\nBenchmarkMultiKeyMapPut/size_1000-12                   36153      33815 ns/op      2883 B/op      900 allocs/op\nBenchmarkMultiKeyMapPut/size_10000-12                   3026     394762 ns/op     39202 B/op     9900 allocs/op\nBenchmarkMultiKeyMapPut/size_100000-12                   248    4571614 ns/op    551453 B/op    99915 allocs/op\n                                                                                 \nBenchmarkMultiKeyMapRemove/size_100-12               2821974        425.8 ns/         0 B/op        0 allocs/op\nBenchmarkMultiKeyMapRemove/size_1000-12                78538      15281 ns/op      2880 B/op      900 allocs/op\nBenchmarkMultiKeyMapRemove/size_10000-12                6922     169382 ns/op     38880 B/op     9900 allocs/op\nBenchmarkMultiKeyMapRemove/size_100000-12                670    1764847 ns/op    518884 B/op    99900 allocs/op\n                                                                                 \n# =\u003e Concurrent \u003c=                                Iterations                                                  \nBenchmarkConcurrentMultiKeyMapGet/size_100-12         735793       1578 ns/op         0 B/op        0 allocs/op\nBenchmarkConcurrentMultiKeyMapGet/size_1000-12         32385      37066 ns/op      2880 B/op      900 allocs/op\nBenchmarkConcurrentMultiKeyMapGet/size_10000-12         2756     433572 ns/op     38880 B/op     9900 allocs/op\nBenchmarkConcurrentMultiKeyMapGet/size_100000-12         240    4950545 ns/op    518883 B/op    99900 allocs/op\n                                                                                 \nBenchmarkConcurrentMultiKeyMapPut/size_100-12         454376       2609 ns/op         0 B/op        0 allocs/op\nBenchmarkConcurrentMultiKeyMapPut/size_1000-12         29721      40303 ns/op      2884 B/op      900 allocs/op\nBenchmarkConcurrentMultiKeyMapPut/size_10000-12         2592     459977 ns/op     39256 B/op     9900 allocs/op\nBenchmarkConcurrentMultiKeyMapPut/size_100000-12         224    5369616 ns/op    555038 B/op    99918 allocs/op\n                                                                                 \nBenchmarkConcurrentMultiKeyMapRemove/size_100-12      490444       2412 ns/op         0 B/op        0 allocs/op\nBenchmarkConcurrentMultiKeyMapRemove/size_1000-12      41236      29073 ns/op      2880 B/op      900 allocs/op\nBenchmarkConcurrentMultiKeyMapRemove/size_10000-12      4030     298559 ns/op     38880 B/op     9900 allocs/op\nBenchmarkConcurrentMultiKeyMapRemove/size_100000-12      400    2968791 ns/op    518884 B/op    99900 allocs/op\n```\n\n## BiKeyMap\n\nThis map has two generic keys, both need to be unique.\nYou can use it like this:\n\n```go\npackage main\n\nimport \"github.com/aeimer/go-multikeymap/bikeymap\"\n\nfunc main() {\n\ttype City struct {\n\t\tName       string\n\t\tPopulation int\n\t}\n\t// keyA: Cityname, keyB: Population\n\tbm := bikeymap.New[string, int, City]()\n\t// or: bm := bikeymap.NewConcurrent[string, int, City]()\n\tbm.Put(\"Berlin\", 3_500_000, City{\"Berlin\", 3_500_000})\n\tbm.Put(\"Hamburg\", 1_800_000, City{\"Hamburg\", 1_800_000})\n\tbm.GetByKeyA(\"Berlin\")  // City{\"Berlin\", 3_500_000}\n\tbm.GetByKeyB(1_800_000) // City{\"Hamburg\", 1_800_000}\n}\n```\n\nBenchmark results (`task gotb`):\n\n```\n# =\u003e Non-Concurrent \u003c=                         Iterations\nBenchmarkBiKeyMapGet/size_100-12                   531668        2094 ns/op          0 B/op         0 allocs/op\nBenchmarkBiKeyMapGet/size_1000-12                   24627       49464 ns/op       2880 B/op       900 allocs/op\nBenchmarkBiKeyMapGet/size_10000-12                   1644      729522 ns/op      38880 B/op      9900 allocs/op\nBenchmarkBiKeyMapGet/size_100000-12                   139     8544642 ns/op     518882 B/op     99900 allocs/op\n                                                  \nBenchmarkBiKeyMapPut/size_100-12                   254956        4653 ns/op          0 B/op         0 allocs/op\nBenchmarkBiKeyMapPut/size_1000-12                   12880       92922 ns/op       5791 B/op      1800 allocs/op\nBenchmarkBiKeyMapPut/size_10000-12                    914     1289536 ns/op      81248 B/op     19800 allocs/op\nBenchmarkBiKeyMapPut/size_100000-12                    67    17404694 ns/op    1436872 B/op    199973 allocs/op\n                                                  \nBenchmarkBiKeyMapRemove/size_100-12               5802380       206.4 ns/op          0 B/op         0 allocs/op\nBenchmarkBiKeyMapRemove/size_1000-12               612367        1984 ns/op          0 B/op         0 allocs/op\nBenchmarkBiKeyMapRemove/size_10000-12               60577       19730 ns/op          0 B/op         0 allocs/op\nBenchmarkBiKeyMapRemove/size_100000-12               5990      199194 ns/op          0 B/op         0 allocs/op\n                                                  \n# =\u003e Concurrent \u003c=                              Iterations               \nBenchmarkConcurrentBiKeyMapGet/size_100-12          325862        3638 ns/op          0 B/op         0 allocs/op\nBenchmarkConcurrentBiKeyMapGet/size_1000-12          19471       61879 ns/op       2880 B/op       900 allocs/op\nBenchmarkConcurrentBiKeyMapGet/size_10000-12          1428      832351 ns/op      38880 B/op      9900 allocs/op\nBenchmarkConcurrentBiKeyMapGet/size_100000-12          100    10026768 ns/op     518882 B/op     99900 allocs/op\n                                                  \nBenchmarkConcurrentBiKeyMapPut/size_100-12          207386        5683 ns/op          0 B/op         0 allocs/op\nBenchmarkConcurrentBiKeyMapPut/size_1000-12          12157       99885 ns/op       5793 B/op      1800 allocs/op\nBenchmarkConcurrentBiKeyMapPut/size_10000-12           870     1371878 ns/op      81438 B/op     19800 allocs/op\nBenchmarkConcurrentBiKeyMapPut/size_100000-12           62    19618138 ns/op    1469608 B/op    199989 allocs/op\n                                                  \nBenchmarkConcurrentBiKeyMapRemove/size_100-12       353018        3667 ns/op       1599 B/op        99 allocs/op\nBenchmarkConcurrentBiKeyMapRemove/size_1000-12       34488       34653 ns/op      15999 B/op       999 allocs/op\nBenchmarkConcurrentBiKeyMapRemove/size_10000-12       3363      364001 ns/op     159952 B/op      9997 allocs/op\nBenchmarkConcurrentBiKeyMapRemove/size_100000-12       320     3551128 ns/op    1595034 B/op     99687 allocs/op\n```\n\n## Contribution\n\nFeel free to contribute by opening issues or pull requests.\nTo set up the project, you need to have go installed.\nThen you can run the following commands:\n\n```bash\n# List Taskfile tasks\ntask\n\n# Install dependencies\ntask setup\n\n# Run tests\ntask test\n\n# Run benchmarks\ntask test-bench\n```\n\n## Star history\n\n[![Star History](https://api.star-history.com/svg?repos=aeimer/go-multikeymap\u0026type=Date)](https://star-history.com/#aeimer/go-multikeymap\u0026Date)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faeimer%2Fgo-multikeymap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faeimer%2Fgo-multikeymap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faeimer%2Fgo-multikeymap/lists"}