{"id":23391303,"url":"https://github.com/robbepop/bucket_vec","last_synced_at":"2025-08-24T01:06:23.839Z","repository":{"id":62438575,"uuid":"241970217","full_name":"Robbepop/bucket_vec","owner":"Robbepop","description":"A vector-like collection that guarantees not to move its internal elements.","archived":false,"fork":false,"pushed_at":"2020-02-24T15:04:21.000Z","size":212,"stargazers_count":3,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-07T00:05:16.019Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Robbepop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-20T19:22:27.000Z","updated_at":"2020-10-26T21:49:59.000Z","dependencies_parsed_at":"2022-11-01T21:16:23.739Z","dependency_job_id":null,"html_url":"https://github.com/Robbepop/bucket_vec","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Robbepop%2Fbucket_vec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Robbepop%2Fbucket_vec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Robbepop%2Fbucket_vec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Robbepop%2Fbucket_vec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Robbepop","download_url":"https://codeload.github.com/Robbepop/bucket_vec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248371963,"owners_count":21093132,"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":[],"created_at":"2024-12-22T04:14:45.844Z","updated_at":"2025-04-11T09:59:18.175Z","avatar_url":"https://github.com/Robbepop.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bucket Vector\n\n|       Docs                       |       Crates.io                        |\n|:--------------------------------:|:--------------------------------------:|\n| [![docs][docs-badge]][docs-link] | [![crates][crates-badge]][crates-link] |\n\n[docs-badge]: https://docs.rs/bucket_vec/badge.svg\n[docs-link]: https://docs.rs/bucket_vec\n[crates-badge]: https://img.shields.io/crates/v/bucket_vec.svg\n[crates-link]: https://crates.io/crates/bucket_vec\n\n## ⚠️ Caution\n\n\u003e USE WITH CAUTION\n\nAs of now this crate has not yet been battle tested\nor benchmarked to an extend where the author would recommend general production\nusage. Please file bugs, suggestions or enhancements to the issue tracker of [this repository](github.com/Robbepop/bucket-vec).\n\n## Description\n\nA vector-like data structure that organizes its elements into a set of buckets\nof fixed-capacity in order to guarantee that mutations to the bucket vector\nnever moves elements and thus invalidates references to them.\n\nThis is comparable to a `Vec\u003cBox\u003cT\u003e\u003e` but a lot more efficient.\n\n## Configs\n\nThe `BucketVecConfig` trait allows to customize the internal structure of your\n`BucketVec`. This allows users to fine-tune their `BucketVec` for particular\nuse cases.\n\nThe trait mainly controls the capacity of the first bucket and the growth rate\nof the capacity of new buckets.\n\nThe default `DefaultConfig` tries to balance out the different interests\nbetween start capacity and growth rate.\n\n## Under the Hood\n\nThe `BucketVec` is really just a vector of `Bucket` instances.\nWhenever an element is pushed to the `BucketVec` the element is pushed onto\nthe last `Bucket` if it isn't filled, yet.\nIf the last `Bucket` is filled a new `Bucket` is pushed onto the `BucketVec`\nwith a new capacity determined by the used bucket vector configuration.\n\nThis way the `BucketVec` never moves elements around upon inserting new elements\nin order to preserve references. When a normal `Vec` is modified it can potentially\ninvalidate references because of reallocation of the internal buffer which\nmight cause severe bugs if references to the internal elements are stored\noutside the `Vec`. Note that normally Rust prevents such situations so the\n`BucketVec` is mainly used in the area of `unsafe` Rust where a developer\nactively decides that they want or need pinned references into another data\nstructure.\n\nFor the same reasons as stated above the `BucketVec` does not allow to remove\nor swap elements.\n\n## Example\n\nLooking at an example `BucketVec\u003ci32\u003e` with the following configuration:\n\n- `start_capacity := 1`\n- `growth_rate := 2`\n\nWe have already pushed the elements `A`,.., `K` onto it.\n\n```\n[ [A], [B, C], [D, E, F, G], [H, I, J, K, _, _, _, _] ]\n```\n\nWhere `_` refers to a vacant bucket entry.\n\nPushing another `L`,.., `O` onto the same `BucketVec` results in:\n\n```\n[ [A], [B, C], [D, E, F, G], [H, I, J, K, L, M, N, O] ]\n```\n\nSo we are full on capacity for all buckets.\nThe next time we push another element onto the `BucketVec` it will create a new `Bucket` with a capacity of `16` since `growth_rate == 2` and our current latest bucket already has a capacity of `8`.\n\n```\n[ [A], [B, C], [D, E, F, G], [H, I, J, K, L, M, N, O], [P, 15 x _] ]\n```\n\nWhere `15 x _` denotes 15 consecutive vacant entries.\n\n## Benchmarks\n\n`BucketVec` fullfills its role in being a replacement for situations where\na `Vec\u003cBox\u003cT\u003e\u003e` is the naive go-to solution.\nThe benchmark suite is still small and not super expressive but already provides\nsome insights in where `BucketVec` already performs pretty well and where it\ncould improve.\n\nBenchmarks have been run on a Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz.\nNote that for every of the benchmark groups (`push`, `get` and `iter`) the\nmost efficient configuration for the `BucketVec` has been chosen.\nSome benchmarks (`get`) have shown significant difference between configs.\n\nThe following is the output of a benchmark run each operating on 10k elements.\n\n```\nbucket_vec::push              time:   [43.647 us 43.861 us 44.108 us]\nbucket_vec::push_get          time:   [48.872 us 49.396 us 49.834 us]\nvec_box::push                 time:   [405.37 us 410.91 us 417.20 us]\nvec_value::push               time:   [25.826 us 25.915 us 26.020 us]\n\nbucket_vec::get (fast config) time:   [17.732 us 17.782 us 17.840 us]\nbucket_vec::get (mid config)  time:   [243.95 us 244.75 us 245.66 us]\nbucket_vec::get (slow config) time:   [341.06 us 350.02 us 361.15 us]\nvec_box::get                  time:   [14.446 us 14.485 us 14.537 us]\nvec_value::get                time:   [8.7939 us 8.8105 us 8.8300 us]\n\nbucket_vec::iter              time:   [4.4195 us 4.4316 us 4.4454 us]\nvec_box::iter                 time:   [9.5925 us 9.6246 us 9.6610 us]\nvec_value::iter               time:   [3.5955 us 3.6043 us 3.6142 us]\n\nbucket_vec::iter_back         time:   [3.9804 us 3.9957 us 4.0144 us]\nvec_box::iter_back            time:   [9.9677 us 9.9980 us 10.033 us]\nvec_value::iter_back          time:   [3.5827 us 3.5944 us 3.6080 us]\n\nbucket_vec::iter_mut          time:   [5.0533 us 5.0710 us 5.0909 us]\nvec_box::iter_mut             time:   [13.425 us 13.845 us 14.203 us]\nvec_value::iter_mut           time:   [4.0172 us 4.0473 us 4.0820 us]\n```\n\nIt can be seen that `BucketVec` greatly outperforms `Vec\u003cBox\u003c_\u003e\u003e` on\n`push`, `iter` and `iter_back` benchmarks.\nHowever, for some configurations `BucketVec::get` is a lot slower than\n`Vec\u003cBox\u003cT\u003e\u003e::get`. The configurations used in the benchmark are:\n\n- `fast` config: `STARTING_CAPACITY = 16; GROWTH_RATE = 1.0;`\n- `mid`  config: `STARTING_CAPACITY =  4; GROWTH_RATE = 2.0;`\n- `slow` config: `STARTING_CAPACITY =  5; GROWTH_RATE = 1.5`\n\nFor other benchmarked operations the difference in performance has not been as significant as for the `get` operation.\n\nAlso `BucketVec` is approximately 50% slower than the `Vec\u003c_\u003e` which is the\ntheoretical optimum that unfortunately doesn't solve the underlying problem.\n\n## Alternatives\n\nBefore you use this data structure make sure that you are really in need of it.\nThe only problem it solves is that `BucketVec::{push, push_get}` guarantee that\nelements stored inside the `BucketVec` are never moved around.\n\n- This can also be achieved by `Vec\u003cBox\u003cT\u003e\u003e` although performance is generally\n  worse for the majority of operations.\n- Note that this is not a solution to store trait objects in a `Vec`!\n- Also note that under certain curcumstances it is possible to instead of a\nstandard Rust `Vec\u003cT\u003e` and make sure that elements won't move upon a `push`\noperation by using `Vec::reserve` or `Vec::reserve_exact` with appropriate\narguments for the use case.\n\nIf none of the above alternative solutions is applicable you might consider\nusing `BucketVec`.\n\n## Authors \u0026 Credits\n\nAuthor: Robin Freyler (github.com/Robbepop)\n\nSpecial thanks to Niklas Tittjung (github.com/lugino-emeritus) who helped me a\nlot with some internal formulae.\n\n## License\n\nLicensed under either of\n\n * Apache license, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Dual licence: [![badge][license-mit-badge]](LICENSE-MIT) [![badge][license-apache-badge]](LICENSE-APACHE)\n\n[license-mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg\n[license-apache-badge]: https://img.shields.io/badge/license-APACHE-orange.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobbepop%2Fbucket_vec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobbepop%2Fbucket_vec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobbepop%2Fbucket_vec/lists"}